user100000 user100000 - 25 days ago 5
C Question

What is a good way to stop all pthreads without using mutex or global variables?

Say hypothetically you do not know about mutex_locks and you are not allowed to use global variables in your program, what can you do in order to stop all running pthreads if one returns a successful variable?

For example you have a data structure that you pass to the pthread that contains :

typedef struct {

char * string1; //info from argv[1]
char * string2; //info from argv[2]

int id; //thread id

} dataStruct;


and while creating the pthreads in main.c you create them as such :

dataStruct dataStr[nbThread]; //array of dataStructs for each thread
pthread_t tabThread[nbThread]; //Pointers for thread 1

for (int i = 0; i < nbThread; ++i) { //initiation of threads...
dataStr[i].string1 = argv[1];

pthread_create(&tabThread[i], NULL, thread, (void *)&dataStr[i]); //create pthreads and
}

for (int i = 0; i < nbThread; ++i) {
pthread_join(tabThread[i], (void**)&(ptr[i])); //join threads
//printf("\n return value from thread[%d] is [%d]\n",i, *ptr[i]);
}


Now one of those threads finds what you were hoping to achieve, how can you get all the threads to stop simultaneously?

Can I have a pointer in the struct that points to a variable in the main that can be changed to true as soon as a thread is successful?

Can I use the return value by the pthreads to somehow stop them all?

I'm having a bit of difficulty understanding the pointers. Any help is appreciated.

Answer

So I found the answer myself in the end. It was much simpler than I assumed.

So in my main I created a "flag" variable as such :

int flag = 0;

Then in my struct I added the following pointer :

int * ptrTrouve;        //ptr on address of flag in main.c

Then while creating all the pthreads and before passing the pthread_create the structs in the parameter, I made ptrTrouve point to the address of the flag. I did it as such

for (int i = 0; i < nbThread; ++i) {            //initiation of threads...

    dataStr[i].id    = i;                       //thread ID in appropriate struct

    dataStr[i].ptrTrouve = &flag;               //where the value of flag is stored

    pthread_create(&tabThread[i], NULL, thread, (void *)&dataStr[i]);   //create pthreads and
}   

Finally in my thread, while the functions run simultaneously, they permanently verify if :

*(dataStr.ptrTrouve) == 0

If one of the threads is successful, they change the value of the flag like this :

*(dataStr.ptrTrouve) = 1;

As each thread is constantly monitoring the value of the flag (*(dataStr.ptrTrouve)) they can all run at the same time. As soon as the flag changes, this is what happens:

if(*(dataStr.ptrTrouve) == 1){              //if successful 
    pthread_exit(NULL);
}

I hope this solution can help others in the future.