I am writing a multi threaded use case, where loop runs continuously in entry()
function and ends when exit_loop()
is called. In the below example, entry()
is called with two threads and the execution of both the thread ends when exit_loop()
is called.
Now I would like to change this a bit by exiting only one thread when exit_loop()
is called first, ie entry()
called from thread[2]
still remains which can be terminated when exit_loop()
is called again. To make these two threads independent I could move the static int loop
to local scope. But I am struck in the way of communicating the loop
status between entry()
and exit_loop()
.
Want to share a common variable between two functions, which must not affect and interfere with multi threaded use case.
#include<stdio.h>
#include<pthread.h>
#include<semaphore.h>
#include<fcntl.h>
static int loop = 1;
void* entry()
{
int count = 0;
while(loop)
{
count ++;
printf("\n Count %d, loop %d",count, loop);
}
}
void exit_loop()
{
printf("\n Calling exit loop: %d", loop);
loop = 0;
printf("\n loop is null %d", loop);
}
void main()
{
sem_t* loop1;
sem_t* loop2;
pthread_t threadID[5];
loop1 = sem_open("sem1", O_CREAT | O_EXCL, 0644, 0);
if (loop1 != SEM_FAILED)
{
printf("\n Created sem 1");
pthread_create(&threadID[1], NULL, &entry, NULL);// creating thread 1
printf("Created thread \n ");
}
else
{
printf("\n Failed to create Semaphore");
}
sem_close(loop1);
loop2 = sem_open("sem2", O_CREAT | O_EXCL, 0644, 0);
if (loop2 != SEM_FAILED)
{
printf("\n Created sem 2");
pthread_create(&threadID[2], NULL, &entry, NULL);//creating thread 2
printf("Created thread \n ");
}
else
{
printf("\n Failed to create Semaphore");
}
sem_close(loop2);
printf("Creating exit thread \n");
exit_loop();// exit of both thread
pthread_join(threadID[1],NULL);
pthread_join(threadID[2],NULL);
}
If you have two threads which need to be stopped independently, you need two loop
variables.
In each case, you need a mutex to protect accesses to the shared loop
variable to prevent undefined behaviour, because the variable is accessed from two threads (the one reading it and the one writing it).
Declare your mutex alongside the variable it protects:
struct protected_loop_var{
pthread_mutex_t mutex;
int value;
};
struct protected_loop_var loop1={PTHREAD_MUTEX_INITIALIZER,1};
struct protected_loop_var loop2={PTHREAD_MUTEX_INITIALIZER,1};
Then, before accessing each loop
variable, lock the mutex, and unlock the mutex afterwards. It is probably easiest to write separate functions for accessing loop to encapsulate this.
static int read_loop(struct protected_loop_var* loop){
pthread_mutex_lock(&loop->mutex);
int value=loop->value;
pthread_mutex_unlock(&loop->mutex);
return value;
}
static void write_loop(struct protected_loop_var* loop,int newval){
pthread_mutex_lock(&loop->mutex);
loop->value=newval;
pthread_mutex_unlock(&loop->mutex);
}
Then your while
in entry
can say while(read_loop(&loopvar))
, and in exit_loop
you can write write_loop(&loopvar,0)
instead of loop=0
where loopvar
is either loop1
or loop2
as appropriate.
If you need to run the same code on each thread then you can pass the address of the loop variable to that thread via the void*
argument.
Other patterns may work for this specific case, but a mutex is the general tool to use for protecting multithreaded accesses to a shared variable.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.