简体   繁体   中英

Sharing common variable between 2 functions in multithreaded environment

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM