2011-09-12 3 views
2

J'ai un fichier main.c avec une variable globale appelée int countboards. Dans le main(), je lance un pthread, qui écoute ONE TCP-Connection et l'exécute (progserver.c). Moyens, ce fil ne reviendra jamais. Dans le main() j'entre la fonction rmmain(...) qui se trouve dans le rm.c (RM = Ressource Manager). Dans rm.c je lis countboards, dans le progserver.c dans le pthread j'écris à cette variable (les deux sont rendus accessibles par extern int countboards). Donc le problème est que quand j'écris à countboards dans le pthread et que je veux accéder à cette variable après qu'elle a été écrite dans le rm.c, elle a toujours l'ancienne valeur (dans ce cas 0 au lieu de par exemple dix). Pourquoi?Accès aux variables globales dans pthreads dans différents fichiers c

main.c:

int countboards; 

int main(int argc, char** argv) { 
    countboards = 0; 
    pthread_t thread; 
    pthread_create(&thread, NULL, startProgramserver, NULL); 

    rmmain(); 

    return 0; 
} 

rm.c:

extern int countboards; 

int rmmain(vhbuser* vhbuserlist, int countvhbuser, 
     userio* useriolist, int countios, int usertorm, int rmtosslserver, int sslservertorm) { 
    while(1) { 
    int n; 
    n=read(usertorm,buf,bufc); // blocks until command comes from the user 
    ... 
    board* b = findAFreeBoard(boardlist, countboards, usagelist); // here countboards should be >0, but it isn't 
    ... 
    } 
} 

programserver.c:

extern int countboards; 
void* startProgramserver(void*) { 
    ... 
    sock = tcp_listen(); 
    ... 
    http_serve(ssl,s, sslpipes); 
} 

static int http_serve(SSL *ssl, int s, void* sslpipes) { 
    ... 
    countboards = countboards + countboardscommands; 
    ... 
    // here countboards has the new value 
} 

Répondre

3

Vous voyez une copie en cache dans chaque thread. Je suggère de le déclarer volatile int countboards sauf que ce n'est vraiment pas une bonne façon de faire les choses.

Les globaux sont un peu mauvais. Vous seriez mieux servi en passant un pointeur sur chaque thread et en synchronisant avec un mutex.

Edit: développiez depuis que je suis pressé hier soir ...

http://software.intel.com/en-us/blogs/2007/11/30/volatile-almost-useless-for-multi-threaded-programming/

Comme KasigiYabu mentions dans les commentaires ci-dessous, la création d'une structure « contexte » qui contient toutes les informations que vous souhaitez partager entre les threads et en passant à pthread_create que le dernier arg est une approche saine et est ce que je fais aussi bien dans la plupart des cas.

+0

Oui, il devrait être déclaré «volatile», mais il devrait également être protégé par un mutex pour assurer l'atomicité. –

+4

Si elle est protégée par un mutex pour les lectures et les écritures, volatile n'est pas nécessaire (et ne fait que nuire aux performances) – bdonlan

+0

passant comme ça? 'pthread_create (& thread, NULL, startProgramserver, & countboards);' et dans le thread allant de void * retour à int? Que faire quand j'ai 2 variables? Comment puis-je passer une variable 'int' et une' board' ('board' est une structure self-made)? – Berschi