Premiers pas vers des entrées sorties optimisées sous Unix et windows

Introduction

L'écriture d'un programme de type serveur Web ou proxy nécessite l'utilisation d'API performantes afin d'obtenir de bonnes performances et une bonne tenue en charge.

Un des problèmes principal qui se pose si on souhaite réaliser un framework de gestion des entrées sortie est celui de la portabilité. En effet, les fonctions performantes pour réaliser ce travail sont différentes d'un systeme à l'autre (solaris, linux, freebsd, win32).

En dehors de cela, le principe est toujours le même : On crée un boucle pour gérer l'ensemble des entrées sortie. Cette boucle est en attente sur un fonction qui va se reveiller chaque fois qu'une entrée sortie a lieu (select(), GetQueuedCompletionStatus()). On détermine de quelle entrée sortie il s'agit (descripteur de fichier et type d'entrée sortie) et on la traite.

// Pseudo code
for(;;)
{
	// Attend une IO
	WaitForIO( ...);

	// Gestion de l'IO
	pFile = GetIOHandle(...);

	switch(typeIO)
	{
		case READ:
			pFile->Read(...);
			break;
		case WRITE
			pFile->Write(...);
			break;
		...
	}
}

Il existe 2 fonctionnements possibles :

select()

Si les performances et la tenue en charge ne sont pas déterminantes, l'implémentation peut se faire en utilisant select(). On note qu'on peut redéfinir FD_SETSIZE sous WIN32 avant l'inclusion de winsock2.h si on souhaite augmenter le nombre de connexions simultanées (64 par défaut)

Les IOCPs

Sous Windows, le choix est vite fait, il faut utiliser le IO completions ports, comme le recommande Microsoft. Voir les API CreateIoCompletionPort(), PostQueuedCompletionStatus(), GetQueuedCompletionStatus()

poll() et aio_*()

Sous Unix, si l'on ne souhaite créer qu'un seul code, il faut se tourner vers poll() ou les fonctions ai_*(). L'avantage de ces dernières est qu'elles ont un fonctionnement proactif, tout comme les IOCP de Windows, contrairement à poll() qui fonctionne de manière réactive.

Sources

L'exemple aio.zip peut servir de point de départ pour créer une API qui surcouche ces différences.

Voir comment utiliser cet API (code)

Liens

Valid XHTML 1.0!