2017-09-02 1 views
0

Ich möchte die ungeraden Zahlen im Haupt-Thread und die geraden Zahlen im neuen Thread drucken. Ich habe versucht, ein Programm zu schreiben, aber es druckte nur ungerade Zahlen, nicht die geraden Zahlen. Ich habe versucht, nach Hinweisen zu suchen, um herauszufinden, was falsch ist, aber ich habe keine gefunden.Kann gerade und ungerade Zahlen nicht asynchron drucken

Dies ist mein Code.

#include<stdio.h> 
#include<stdlib.h> 
#include<pthread.h> 
#define MAX 1000 

int count = 0; 

void print_odd_numbers(); 
void *print_even_numbers(); 

int main() { 
    pthread_t t; 
    int iret; 
    iret = pthread_create(&t, NULL, print_even_numbers, NULL); 
    print_odd_numbers();   
    pthread_join(t, NULL); 
    return 0; 
} 

void print_odd_numbers() { 
    while(count <= MAX) { 
     if(count % 2 == 1) { 
      printf("%d\n", count); 
     } 
     count++; 
    } 
} 

void *print_even_numbers() { 
    while(count <= MAX) { 
     if(count % 2 == 0) { 
      printf("%d\n", count); 
     } 
     count++; 
    } 
    pthread_exit(NULL); 
} 
+2

Jeder Thread benötigt seine eigene Variable 'count'. Benutze keine Globals! –

+0

@MartinJames Ich habe viele Programme gesehen, in denen sie die Anzahl global halten. Eigentlich sollten die beiden Threads parallel laufen, also sollte die Anzahl, auf die sie verweisen, gleich sein. Nach meinem Wissen. Bitte helfen Sie, wenn ich falsch liege. –

+1

@Priyanka Naik Nein, das ist falsch. Der Grund hat mit CPU-Cache-Kohärenz zu tun. Sofern Sie keine spezifischen Operationen verwenden, die einen gemeinsamen Wert in einer Cache-kohärenten Weise atomar inkrementieren, können Sie zwei CPUs (oder Kerne) haben, die jeweils über ihre eigene Kopie der Variablen im Cache iterieren und dann ihre Kopie zurückschreiben Irgendwann. Außerdem muss der Compiler den Wert nicht erneut aus dem Speicher lesen, aber das ist eine andere Geschichte. –

Antwort

1

Die Tatsache, dass beide print_odd_numbers und print_even_numbers Zuwachs count auch wenn sie die Quelle hier viel von der Mühe nichts drucken.

Alle Schritten count wird in print_odd_numbers gemacht werden, und count wird MAX vor print_even_numbers wird gestartet eingestellt werden.

machen count lokal zu den Funktionen helfen könnte, oder ist viel vorsichtiger, wie count erhöht wird eine andere Art und Weise ist - wenn man seine globale Natur behalten, dann sollten Sie mit Atom-Schritten betrachten.

+0

ok .. wird versuchen, sie lokal zu halten Eine Funktion –

+0

Nach meinen Angaben sollten sich die Threads einen gemeinsamen Adressraum teilen, also sollten beide Threads einen gemeinsamen Variablen-Count haben, außerdem sollten die Prozesse parallel laufen –

+0

Oder verwenden Sie einen Mutex, der den Zugriff auf die Ressource sichert ('count') geteilt zwischen Threads. –

0

Wenn Sie den Compiler nicht wissen lassen, dass Ihre Zählung von mehreren Threads verwendet wird, dann kann komplett Ihren Code neu anordnen. Zum Beispiel veränderte der Compiler wahrscheinlich print_odd_numbers auf etwas mehr wie

void print_odd_numbers() { 
    if (count <= MAX) { 
     if(count % 2 == 1) { 
      printf("%d\n", count); 
     } 
     count++; 
    } 
    while(count <= MAX) { 
     printf("%d\n", count); 
     count += 2; 
    } 
} 

Außerdem ist jede CPU oder Kern wird mit einem eigenen Kopie count arbeiten, weil wir all diesen ehrfürchtigen CPU haben Caches, die Geschwindigkeit Dinge so viel nach oben. Wenn Sie Ihrem Compiler nicht mitteilen, dass dieser Speicherort von anderen Threads verwendet wird, verwendet jeder Thread (wenn er auf seinem eigenen Kern ausgeführt wird) nur seine eigene Kopie und schreibt diesen Wert irgendwann in den Hauptspeicher zurück.

Sie müssen eine atomare Inkrement-Anweisung verwenden oder Ihre globale mit einem Mutex, kritischen Abschnitt, Semaphor usw. schützen. Wenn Sie Semaphore, Mutexe usw. verwenden, generiert der Compiler automatisch eine LOCK-Anweisung (auf x86 oder ähnlich für andere Archs), die die CPU zwingt, Speicher in ihrem Cache auf kohärente Weise über CPUs und Kerne hinweg zu verwalten.

pthreads: If I increment a global from two different threads, can there be sync issues?

Verwandte Themen