I want to create 2 Threads, which are in use of a global variable, my code:
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
int var = 0; //
pthread_t threads[2];
void* function(){
if(var % 2==0){
var =2;
}
printf("Addresse %d with var %d\n", &var, var);
}
int main() {
for(int i = 0; i < 2; i ){
pthread_create(&threads[i], NULL, &function, NULL);
}
pthread_exit(NULL);
}
I created 2 threads with the for loop. I want to let both threads use the global variable. One shall increment 2, the other thread shall multiply 2. I used printf to see, that both use same addresse, but not have same output. How do I let each of the threads to different tasks?
CodePudding user response:
How do I let each of the threads to different tasks?
One way to do this is to write a separate thread function for each thread. In that case, it would be easier to start each via its own pthread_create()
call instead of using a loop.
If you must use the same thread function, but you want it to do different work in the two cases then the easiest thing to do is use the thread function's argument (which your code fails to declare). For example:
void *function(void *arg) {
if ((intptr_t) arg == 0) {
// do one thing ...
} else {
// do a different thing ...
}
return /* something */;
}
int main(void) {
// ...
for(intptr_t i = 0; i < 2; i ) {
pthread_create(&threads[i], NULL, &function, (void *) i);
}
// ...
}
Note also, however, that if your threads both access the same non-atomic global variable, and at least one of them modifies it, then you must synchronize their access so that they cannot access it at the same time. There are several ways to do that, but the most conventional is to provide a mutex that each thread locks before accessing the variable and unlocks after.
CodePudding user response:
The simplest way to safely share a variable between multiple threads is to use a mutex (MUTual EXclusion). I modified your program to use one. Note that it locks around the area which the variable is checked and modified. While mutex'es are simple for this sort of application, other appications which might involve waiting for a var
to have a particular value would require something like condition variables (pthread_cond_t). This is a rich field of options for different needs; but this should get you started:
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
int var = 0; //
pthread_mutex_t varlock = PTHREAD_MUTEX_INITIALIZER;
#define NTH 20
pthread_t threads[NTH];
void* function(){
int val;
pthread_mutex_lock(&varlock);
if(var % 2==0){
var =2;
}
val = var;
pthread_mutex_unlock(&varlock);
printf("Addresse %d with var %d\n", &var, val);
}
int main() {
for(int i = 0; i < NTH; i ){
pthread_create(&threads[i], NULL, &function, NULL);
}
pthread_exit(NULL);
}
CodePudding user response:
You should refer to What is a race condition?. This is a classic example of a multi-threaded race condition, where two threads are reading and writing to the same memory address.
Edit: You're also passing the same function as the starting point to both threads. They both check if the value is even, and if so, add two to the value.
If you want one thread to add and the other to multiply the value then you could use two functions (I'm also using the mutex variables that mevets recommended for synchronization). Your code is going to be non-deterministic either way
void* add(){
int val;
pthread_mutex_lock(&varlock);
if(var % 2==0){
var =2;
}
val = var;
pthread_mutex_unlock(&varlock);
printf("Addresse %d with var %d\n", &var, val);
}
void* multiply(){
int val;
pthread_mutex_lock(&varlock);
if(var % 2==0){
var *=2;
}
val = var;
pthread_mutex_unlock(&varlock);
printf("Addresse %d with var %d\n", &var, val);
}
int main(){
pthread_create(&threads[0], NULL, &add, NULL);
pthread_create(&threads[1], NULL, &multiply, NULL);
pthread_exit(NULL);
}
You may get a different output every-time you run this code, because it is non-deterministic.