Posix threads



  • Hmm, so ganz klar ist mir die Sache noch nicht.

    Wird die Funktion pthread_create für jeden der NUM_THREADS aufgerufen? Wo inkrementiere ich sinnvollerweise meine Variablen?

    #include <pthread.h>
    #include <stdio.h>
    #define NUM_THREADS     10
    
    struct thread_data{
       int  x;
       int  y;
    };
    struct thread_data thread_data_array[NUM_THREADS];
    
    void *PrintHello(void *threadarg)
    {
    	 struct thread_data *my_data;
    	   my_data = (struct thread_data *) threadarg;
    	   int x = my_data->x;
    	   int y = my_data->y;
               printf("x + y #%ld #%ld!\n", x, y);
    	   for (int i= x; i< y;i++){
    		   printf("Hello World! It's me, thread #%ld!\n", x);
    	   }
    }
    
    int main (int argc, char *argv[])
    {
       pthread_t threads[NUM_THREADS];
       int x,y,rc;
       long t;
       for(t=0; t<NUM_THREADS; t++){
            x= 0;
    	y= 100;	
    	thread_data_array[t].x = x;
       	thread_data_array[t].y = y;
            printf("In main: creating thread %ld\n", t);
            rc = pthread_create(&threads[t], NULL, PrintHello, (void *)&thread_data_array[t]);
       	x = x + y;
            y= y +y;
       }
       pthread_exit(NULL);
    }
    

    Es scheint aber so, dass die Threads nicht wirklich autark von einander die Funktion PrintHello aufrufen? Kann man das realisieren?

    Danke



  • Hallo,

    ich habe nach wie vor ein wenig Probleme mit der Nutzung von POSIX Threds. Der Ober Thread ist obsolet.

    Ein anderes, exemplarisches, Beispiel:

    Die globale Variable a kann ich mittels pthread_mutex_lock/pthread_mutex_unlock vor Inkonsistenzen schützen.

    Wie bekomme ich das für eine Vielzahl globalen Funktionen hin, die von der ersten, vom Thread initialisierten Funktion, aufgerufen werden?

    Ich kann ja schlecht jede Funktion, für die ganze Anzahl von Threads durchnummerieren, und funktion1(b), funktion2(b) erstellen. Das wäre doch unsauber.

    void *PrintHello1(void *threadarg)
    {
         int b;
         Zugriff auf globale Variable a;
         int c = funktion(b);
    }
    void *PrintHello2(void *threadarg)
    {
         int b;
         Zugriff auf globale Variable a;
         int c = funktion(b);
    }
    
    funktion(b){
        ....
        return abc;
    }
    
    int main (int argc, char *argv[])
    {
    ....
            rc = pthread_create(&thread1, NULL, PrintHello1, (void *)&thread_data_array[t]);
            rc = pthread_create(&thread2, NULL, PrintHello2, (void *)&thread_data_array[t]);
    
    ....
    }
    


  • Wo liegt das Problem?

    Du kannst doch sowohl in PrintHello1 als auch in PrintHello2 die funktion(b) aufrufen.

    Wenn du in dieser Funktion auf die Globale Variable "a" zugreifst, dann musst diese Variable eben durch eine criticalsection oder wasauchimmer schützen. Dabei ist völlig Wurst, woher ( von welchem Thread ) der Aufruf dieser Funktion kam.

    Wenn schon jemand die Variable am Wickel hat, müssen alle anderen eben warten.



  • Hi,
    nun, meine Frage zielte auf etwas anderes hinaus. Und zwar, angenommen ich übergebe der funktion() aus mehren Threads eine Variable vom selben Typ. In der Funktion finden Berechnungen statt. Kann es hier zu Inkonsistenzen kommen? Oder wird die Funktion function(b) von jedem Thread autark für sich aufgerufen?



  • Die Funktion wird ja von jedem Thread aufgerufen. Eine Funktion kann man ja auch einfach als Blackbox betrachten. Es gehen Daten rein und es kommen welche raus.
    Solange du in dieser Funktion NICHT auf gemeinsame Daten schreibend zugreifst, brauchst du auch keine Absicherung.



  • Habe ich mit dieser Konstellation den konkurrierenden Zugriff auf den globalen struct in Griff. Oder muss ich vor jeder Variablen ein Lock setzen?

    struct data{
         a,b,c,d;
    
    }
    ...
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    ..
    
    void *PrintHello1(void *threadarg)
    {
         int b;
         Zugriff auf globale Variable a;
         int c = funktion(b);
    }
    void *PrintHello2(void *threadarg)
    {
         int b;
         Zugriff auf globale Variable a;
         int c = funktion(b);
    }
    
    funktion(b){
       pthread_mutex_lock(&mutex); 
       a = a +1;
       b = b + 3;
       c..
       d..
       pthread_mutex_unlock(&mutex);
    }
    
    int main (int argc, char *argv[])
    {
    ....
            rc = pthread_create(&thread1, NULL, PrintHello1, (void *)&thread_data_array[t]);
            rc = pthread_create(&thread2, NULL, PrintHello2, (void *)&thread_data_array[t]);
    
    ....
    }
    


  • Du verwendest doch die globale Struktur garnicht 😃

    Falls ich aber richtig vermute, dass a b c d in der "Funktion" sich auf das globale struct beziehen musst du dort die locks setzen, weil ja sowohl aus printhello1 als auch aus printhello2 die "Funktion" aufgerufen wird.



  • Danke für die Antwort..

    Also das globale struct sollin der function() angesprochen/bearbeitet werden.

    Ich setzt also im struct die mutexvariablen, oder wie meinst du?

    Ich dachte mit pthread_mutex_lock(&mutex); sperre ich den nachfolgenden Bereich, also die Variablenzugriffe bis zum pthread_mutex_unlock(&mutex); für die anderen Threads?



  • firsttime schrieb:

    Ich dachte mit pthread_mutex_lock(&mutex); sperre ich den nachfolgenden Bereich, also die Variablenzugriffe bis zum pthread_mutex_unlock(&mutex); für die anderen Threads?

    Ja genau und das ist auch richtig so. Mehr ist nicht zu tun.

    Ich hab das nur etwas unglücklich formuliert. In dem Struct brauchst du keine Mutexes einbauen 😃 So wie du das in "Funktion" mit den Mutexes gemacht hast, ist das ok.



  • firsttime schrieb:

    Habe ich mit dieser Konstellation den konkurrierenden Zugriff auf den globalen struct in Griff. Oder muss ich vor jeder Variablen ein Lock setzen?

    struct data{
         a,b,c,d;
    
    }
    ...
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    ..
    
    void *PrintHello1(void *threadarg)
    {
         int b;
         Zugriff auf globale Variable a;
         int c = funktion(b);
    }
    void *PrintHello2(void *threadarg)
    {
         int b;
         Zugriff auf globale Variable a;
         int c = funktion(b);
    }
    
    funktion(b){
       pthread_mutex_lock(&mutex); 
       a = a +1;
       b = b + 3;
       c..
       d..
       pthread_mutex_unlock(&mutex);
    }
    
    int main (int argc, char *argv[])
    {
    ....
            rc = pthread_create(&thread1, NULL, PrintHello1, (void *)&thread_data_array[t]);
            rc = pthread_create(&thread2, NULL, PrintHello2, (void *)&thread_data_array[t]);
    
    ....
    }
    

    Warum schreibst Du 2 mal die gleiche Funktion? Wie wäre es mit:

    struct data{
         a,b,c,d;
    
    }
    ...
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    ..
    
    void *PrintHello(void *threadarg)
    {
         int b;
         Zugriff auf globale Variable a;
         int c = funktion(b);
    }
    
    funktion(b){
       pthread_mutex_lock(&mutex); 
       a = a +1;
       b = b + 3;
       c..
       d..
       pthread_mutex_unlock(&mutex);
    }
    
    int main (int argc, char *argv[])
    {
    ....
            rc = pthread_create(&thread1, NULL, PrintHello, (void *)&thread_data_array[t]);
            rc = pthread_create(&thread2, NULL, PrintHello, (void *)&thread_data_array[t]);
    
    ....
    }
    

Anmelden zum Antworten