création de threads + sockets asynchrones portable win32/linux - C++ - Programmation
Marsh Posté le 31-12-2003 à 16:11:47
blackgoddess a écrit : Bonjour, |
oui, les threads+mutex+semaphore+cond posix ont étés portés sous win32, et c'est très pratique
l'implémentation est tout à fait correcte et la mailing-list est très réactive en cas de problèmes (qui sont assez rares)
http://sources.redhat.com/pthreads-win32/
edit:
http://www.google.fr/search?q=win3 [...] ogle&meta=
Marsh Posté le 31-12-2003 à 16:14:18
oui dsl pour le manque de recherche avant de poster, j'etais sur ce lien au moment de ta réponse
et pour les sockets asynchrones ?
Marsh Posté le 31-12-2003 à 16:18:20
qu'est-ce que tu entends par sockets asynchrones ?
Marsh Posté le 31-12-2003 à 16:25:24
bien par exemple sous windows on peut associer un thread a un evenement (WSAEventSelect), ou on peut l'associer a une fenetre ou il enverra ses messages (WSAAsynSelect)
je voudrais savoir s'il etait possible de faire qqchose comme ca de facon portable (je ne vois pas comment faire avec select), en effet avec les evenements comme avec les messages de la fenetres on peut gérer plusieurs "éléments" en meme temps : la fenetre peut recevoir des evenement de plusieurs "éléments", comme on peut attendre plusieurs evenements en meme temps (WSAWaitForMultipleEvents)
Marsh Posté le 31-12-2003 à 16:49:25
Pour leur implémentation portable d'une VM .NET (rotor) les mecs de MS ont développé une couche unix pour certaines API win32 (Portable Adaptation Layer).
Apparemment pour les gérer les API asynchrones, ils passent par un système de thread dédié et de pipe pour communiquer avec.
D'ailleurs pour implémenter le WaitForMultipleObjects ils font pareil.
tu peux télécharger le source pour t'en inspirer sur http://www.microsoft.com/downloads [...] laylang=en
Il y a sans doute d'autres manières (et sûrement plus performantes) d'y arriver.
Mais la question est aussi de savoir si il est raisonnable d'utiliser des API spécifiques à un OS si on veut faire un truc portable.
Marsh Posté le 31-12-2003 à 18:13:13
BlackGoddess,
Pour développer le service NT (post que tu connais bien), j'utilise les fonctions socket (setsockopt, select, send, recv et accept) qui, bien que fournis par winsock2.h, sont - normalement - portable sous linux (seul regret concernant la portabilité : sous windows il faut pratiquer un appel à la procédure WSAStartup() d'initialisation de WS2_32.lib).
Avec thread et select(), j'arrive à mes fins facilement. Je te recommande comme lecture de chevet les articles du dernier hors série de Linux Magasine "reseau/système C" de janvier/février/mars 2004. C'est de niveau débutant/initié, j'espere ne pas t'offenser
Par contre, j'ai cédé en matière de portabilité pour tout le reste (thread et mutex). Je n'ai pas d'IHM donc les conséquences sont limités. Je suis particulièrement interessé par les thread posix (j'aurais du moi aussi réaliser une recherche à ce sujet avant de lacher prise et faire du non portable à la win32).
Cordialement,
Xter.
Marsh Posté le 31-12-2003 à 18:36:37
merci beaucoup pour toutes ces reponses, je pars me documenter de ce pas
Marsh Posté le 04-01-2004 à 14:28:08
pour en revenir aux threads, j'ai trouvé également chez boost : en effet j'avais vu les objets mutex (recursive_mutex, etc ...) et lock, mais je n'avais pas vu boost::thread et boost::thread_group.
donc egalement www.boost.org (boost.threads)
Marsh Posté le 05-01-2004 à 12:19:59
SoWhatIn22 a écrit : |
Je tente de l'utiliser, mais mon code générère une grosse fuite de mémoire et il semblerait que pthread_exit() soit buggée... je creuse, je creuse ca vient sans doute de ma facon d'utiliser la dll.
Cordialement,
Xter.
Marsh Posté le 05-01-2004 à 17:40:30
une petite question :
est-ce sain d'appeler select en mode bloquant (timeout != 0) avec dans une des structures fd_set un socket, et pendant ce temps la dans un autre thread de fermer ce meme socket (close / closesocket) ?
Marsh Posté le 05-01-2004 à 17:46:36
Je ne pense pas que cela pose un problème à condition que tu precises une valeur de time-out. En effet, si tu fermes le socket, l'instruction select() ne pourra se terminer correctement qu'en time out. Si tu oublies le time-out ton thread qui contient le select() reste bloqué.
Cela dit, j'ai du mal à imaginer un cas d'application concret dans lequel tu rencontrerais le type d'architecture dont tu parles.... ce n'est pas de mon code dont tu parles quand même, rassures moi ?
Cordialement,
Xter.
Marsh Posté le 05-01-2004 à 19:29:31
pas de ton code du tout non
je pensais par exemple:
un serveur pour une application multithread dont les traitements son asynchrone, a un thread qui attend ce qu'on pourrait appeler des evenements des sockets, un autre qui fait les traitements, une file de message entre les 2. on va dire par exemple que pour terminer une connexion convenablement le client doit envoyer un message d'au revoir au serveur, et le serveur ferme la connexion. a ce moment la, si le thread de traitement a une charge importante, il y a de fortes chances que lorsqu'il traitera le message d'au revoir du client et fermera le socket, l'autre thread sera en train d'attendre un message d'un socket (avec select).
ta reponse m'amene une autre question : que se passe-t-il si à la fin d'un select, si suivant l'exemple précédent un autre socket du fd_set a recu des données on test avec FD_ISSET un socket qui a été fermé ?
Marsh Posté le 05-01-2004 à 19:41:55
(apres une lecture rapide de ton dernier post)
j'avais le même genre d'architecture en tête pour faire un serveur http et finalement c'est bien plus simple et séquentiel (en particulier pour du multisession).
L'idée, c'est de créer un thread principal qui gère accep() et ensuite autant de threads que de connexions aux clients. Les threads client ne se terminent que lorsque le client se déconnecte ou lorsque le serveur déconnecte le client. Ainsi tu n'as aucun risque d'avoir deux threads concurrent gérant séparément le même socket.
Par contre, il faut eviter de créer des threads gérant le même socket (par exemple des threads secondaires crées à partir d'un même thread client : tu retomberais dans le probleme qui t'ennuie).
Pour revenir à ton exemple, je n'ai pas expérimenté! FD_ISSET indique dans la liste de socket passée à SELECT() si le socket que tu passes en argument est actif suite à un SELECT()... s'il est fermé SELECT() ne risque pas de rendre le socket actif et donc FD_ISSET retourne false. Par contre l'appel de FD_ISSET avec pour argument un identifiant qui ne correspond plus à rien (socket fermé) pourrait éventuellemet perturber l'execution du code (a vrai dire je pense que ca passerait sans probleme mais on ne sait jamais)....
Xter.
Marsh Posté le 05-01-2004 à 21:53:05
oui, mais je me demandais s'il n'etait pas possible de trouver un moyen moins gourmand en ressources systèmes ? à moins qu'un thread ne consomme pas bcp de ressources ?
imagine si tu as 70 clients simultanés tu auras au moins 71 threads ?
sinon également (ce n'est pour l'instant pas mon objectif, mais j'y pense quand même) apparement par exemple sous windows2000 un processus ne peut pas avoir plus de 1024 threads.
alors que si chaque thread gere 64 sockets (le maximum autorisé) on peut aller avec cette valeur jusqu'a 65536 (surement que le système sera saturé avant).
bon, ca part un peu en delire ...
Marsh Posté le 05-01-2004 à 22:03:29
Comme tu l'avais exposé, il te faut donc gérer dynamiquement une liste de socket (1 serveur + N clients) et créer un thread a chaque evenement sur l'un des socket de cette liste (avec SELECT()). Et dans ce cas, on retombe sur le probleme que tu a énnoncé... le risque est de fermer un socket alors qu'il est en cours de traitement par SELECT().
Dans ton thread de deconnexion quio contient un close(socket), il te faut fermer le socket qu'une fois l'instruction SELECT() passée dans le thread principal. Un mutex me parait être la solution la plus evidente pour synchroniser ces deux evennements.
Par curiosité, tu programmes quel genre d'appli serveur ? Un IRC-like...
Bon courage.
Marsh Posté le 12-03-2004 à 00:42:50
Pour revenir au thread POSIX, la portabilité se fait tres bien sous windows grace à la lib Pthread Win32 http://sources.redhat.com/pthreads-win32/
Pour le pthread_exit qui plante, c'est certainement parceque tu fais du C++. Tu devra alors modifier le code source de la lib c'est indiqué.
Voila ++
Marsh Posté le 12-03-2004 à 08:52:51
Ok merci. Je n'avais pas remarqué qu'il falait modifier le code de la lib pour C++. Je vais regarder ca...
Cordialement,
Xter.
Marsh Posté le 12-03-2004 à 10:03:38
BlackGoddess a écrit : Bonjour, |
La meilleure librairie pour faire ce que vous voulez se nomme ACE (Adaptive Communication Environment). Elle gère à peu près tous les appels système de base (threads, sockets, shared mem, file system, mutex, sémaphores & cie, ...).
Elle est un peu grosse, un peu compliquée à utiliser au début, mais elle est très performante et totalement portable. Vous la trouverez ici : http://www.cs.wustl.edu/~schmidt/ACE.html
Citation : |
Marsh Posté le 12-03-2004 à 20:15:03
ah, j'en avais entendu parler uniquement de nom il paraitrait que c'est une usine a gaz
je vais aller voir, merci DocMaboul
Marsh Posté le 31-12-2003 à 15:53:16
Bonjour,
je voudrais créer des threads et des sockets asynchrones pour une application portable win32/linux.
je voudrais savoir s'il existait deja des libraires pour ca ?
par exemple une librairie sous windows qui implémente les threads posix ?
---------------
-( BlackGoddess )-