2017-03-18 2 views
-1

Das C-Programm, das ich in Linux schreibe, erstellt mehrere Threads (in diesem Fall 8) und jeder Thread sollte die Funktion compute() ausführen, die eine globale Variable "total" um 1000 erhöhen wird. Das Programm arbeitet derzeit wie erwartet in dieser Hinsicht, da es die endgültige Summe als 8000 ausgibt.Schutz globaler Variable bei Verwendung mehrerer Threads

Im Moment ist die Reihenfolge, in der die Threads die Compute-Funktion ausführen und die Variable "total" ändern, egal, aber ich möchte sicherstellen dass jeder Thread die globale Variable nicht ändert, bis er von keinem anderen Thread verwendet wird.

Wenn mir jemand in die richtige Richtung zeigen könnte, wie ich POSIX Semaphoren implementieren soll, wäre das sehr zu begrüßen, da dieser Bereich/Threads im Allgemeinen für mich neu ist.

Der aktuelle Code für das Programm ist unten. Vielen Dank!

#include <stdio.h> 
#include <stdlib.h> 
#include <math.h> 
#include <pthread.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include <semaphore.h> 

#define N 8 /* define the total number of processes we want */ 
/* Set global variable */ 
float total=0; 

/* compute function just does something. */ 
int compute() 
{ 
    int i; 
    float oldTotal =0, result =0; 

    /*for a large number of times just square root and square the arbitrary number 1000*/ 
    for (int i = 0; i < 2000000000; i++) //Arbitrary number to allow process to run for a while. 
     { 
     result = sqrt(1000.0)*sqrt(1000.0); 
     } 

    /*Print the result - should be no suprise*/ 
    printf("Result is %f\n", result); 

    /*We want to keep a running total in the global variable total*/ 
    oldTotal = total; 
    total = oldTotal + result; 

    /*Print the running total so far*/ 
    printf("Total is %f\n", total); 
    return(0); 
} 


void* thread_procedure(void* param) 
{ 

    int i = (int)param; 
    /* give a message about the proc ID */ 
    printf("Process Id for process %d is %d\n",i,getpid()); 
    /* call the function to do some computation. If we used sleep 
    The process would simply sleep. We do not want that */ 

    compute(); 

    return NULL; 
} 


int main() 
{ 
    int i, j; 
    sem_init(&mutex, 0, 1); //Initialise mutex 
    pthread_t thread[N]; //Array of threads, N number of processes  


    printf("\n"); /* bit of whitespace */ 
    /* We want to loop to create the required number of processes 
    Note carefully how only the child process is left to run */ 
    for(i=0;i<N;i++) 
    { 
     /* start new thread and catch it if it/one fails */ 
     j = pthread_create(&thread[i], NULL, &thread_procedure, (void*)i); 
     if (j) 
      { 
      printf("Error"); 
      exit(1); 
      } 
    } 


    /* joining with threads */ 
    for(i=0;i<N;i++) 
     { 
      pthread_join(thread[i], NULL); 
     } 

    sem_destroy(&mutex); 
    /* nothing else to do so end main function (and program) */ 
    return 0; 
} // end function: main 
+1

[** Mut ** ual ** Ex ** Verschleierung] (http://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread_mutex_lock.html) – StoryTeller

+0

https://computing.llnl.gov/tutorials/pthreads/# Mutexes – user5159806

Antwort

0

Wenn ich die Verwendung von pthread könnte darauf hindeuten, mutex, die auch die gegenseitige Ausgrenzung gemeinsam genutzte Variablen erreicht, das folgende Beispiel erreicht. Es könnte schneller sein in dem, was Sie erreichen wollen.

#include <pthread.h> 

//Shared global variable 
float total = 0; 

//Shared lock 
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; 

//some thread function that adds 1,000 to total one thread at a time 
void *compute(){ 

    //If no thread is using the lock, acquire lock and add 1,000 to total. The lock prevents other threads from executing this piece of code during a context switch. 
    pthread_mutex_lock(&lock); 
    total += 1000; 
    //Release lock 
    pthread_mutex_unlock(&lock); 

    return NULL; 

} 

diese Weise, wenn die Funktion Thread T1 compute ausführt und die Sperre frei ist, wird er das Schloss, Inkrementieren insgesamt, erwerben und dann die Verriegelung freizugeben. Wenn der Thread T2 compuate aufruft, während T1 über die Sperre verfügt, kann T2 nicht über diesen Punkt im Code hinaus fortgesetzt werden und wartet, bis die Sperrressource von T1 freigegeben wird. So schützt es die globale Variable; Threads, die freigegebene Variablen ändern möchten, können dies nicht zur gleichen Zeit tun, während ein Thread die Sperre hält.

+0

Danke, ich ging mit dieser Lösung! – Ryan

0

Klingt wie Sie verwenden müssen Mutex oder den Semaphore des

Verwandte Themen