Bonjour à tous,
Je suis en train de faire un client/serveur. Dans le serveur, j'aimerais y mettre 2 threads par connexion: l'une fait un fread() et attend des données du client (signaux), pendant que l'autre fait un fwrite() et envoie des données au client (évènements).
Le problème, c'est que la connexion, une socket réouverte avec fdopen(), n'est pas du tout thread safe: lorsque j'essaye de faire un fread() en même temps qu'un fwrite() le signal SIGABORT est levé au moment où le flux est fermé avec fclose().
J'ai essayé de dupliquer le flux d'entrée avec dup(), mais là encore, dup() ne fait qu'un alias, et fwrite() semble n'avoir aucun effet: les données ne sont pas reçues par le client, et ça replante avec SIGABORT. Il semble que celà ne devrait pas fonctionner car le flux créé par dup() partage par exemple la même position de tête de lecture.
Quelqu'un peut-t-il m'aider? Merci.
Code de la thread principale (fread) :
Code :
- // open connexion
- FILE* f=fdopen(sock, "r+" );
- if(!f)
- {
- perror(NULL);
- printf("Cannot turn the socket into a stream\n" );
- close(sock);
- return 0;
- }
- // ...
- // start event thread
- EventThread event_thread;
- if(!event_thread.start(f)) // pthread_create
- {
- printf("Error starting event thread\n" );
- fclose(f);
- return 0;
- }
- // ...
- while(1)
- {
- // read signal
- char c;
- if(fread(&c, 1, 1, f)!=1) break;
- bool quit=0;
- switch(c)
- {
- case 0:
- {
- printf("signal received\n" );
- event_thread.enqueue(EVT_TEST);
- } break;
- case -1: quit=1; break;
- default: break;
- }
- if(quit) break;
- }
- // ...
- event_thread.stop(); // send EVT_QUIT event + pthread_join
- fclose(f);
|
Code de la thread évènementielle (fwrite) :
Code :
- static void* event_thread(void* arg)
- {
- EventThread* event_thread=(EventThread*)arg;
- while(1)
- {
- // wait for an event
- Event* event=event_thread->dequeue();
- bool quit=0;
- switch(event->type)
- {
- case EVT_QUIT:
- {
- quit=1;
- } break;
- case EVT_TEST:
- {
- printf("create event\n" );
- char c=20;
- if(fwrite(&c, 1, 1, event_thread->f)!=1) { quit=1; break; }
- printf("event created\n" );
- } break;
- default: break;
- }
- delete event;
- if(quit) break;
- }
- return 0;
- }
|
Message édité par nargy le 17-05-2010 à 11:34:21