简体   繁体   English

在多线程环境中的 2 个函数之间共享公共变量

[英]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.我正在编写一个多线程用例,其中循环在entry()函数中连续运行,并在exit_loop()时结束。 In the below example, entry() is called with two threads and the execution of both the thread ends when exit_loop() is called.在下面的示例中,使用两个线程调用entry()并且在调用exit_loop()时两个线程的执行结束。

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.现在我想通过在第一次调用exit_loop()时只退出一个线程来稍微改变一下,即从thread[2]调用的entry()仍然存在,当再次调用exit_loop()时可以终止它。 To make these two threads independent I could move the static int loop to local scope.为了使这两个线程独立,我可以将static int loop移动到本地范围。 But I am struck in the way of communicating the loop status between entry() and exit_loop() .但是我对在entry()exit_loop()之间传递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.如果您有两个需要独立停止的线程,则需要两个loop变量。

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).在每种情况下,您都需要一个互斥锁来保护对共享loop变量的访问,以防止出现未定义的行为,因为该变量是从两个线程访问的(一个读取它,一个写入它)。

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.然后,在访问每个loop变量之前,锁定互斥量,然后再解锁互斥量。 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.然后你的while in entry可以说while(read_loop(&loopvar)) ,在exit_loop中你可以写write_loop(&loopvar,0)而不是loop=0其中loopvarloop1loop2视情况而定。

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.如果您需要在每个线程上运行相同的代码,那么您可以通过void*参数将循环变量的地址传递给该线程。

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.其他模式可能适用于这种特定情况,但互斥量是用于保护对共享变量的多线程访问的通用工具。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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