c - 在多线程环境中两个函数之间共享公共(public)变量

标签 c linux multithreading pthreads

我正在编写一个多线程用例,其中循环在 entry() 函数中连续运行,并在调用 exit_loop() 时结束。在下面的示例中,使用两个线程调用 entry(),并且当调用 exit_loop() 时,两个线程的执行都会结束。

现在我想稍微改变一下这一点,在首先调用 exit_loop() 时仅退出一个线程,即从 thread[ 调用 entry() 2] 仍然保留,当再次调用 exit_loop() 时可以终止。为了使这两个线程独立,我可以将静态 int 循环移动到本地范围。但我对 entry()exit_loop() 之间传达 loop 状态的方式感到震惊。

想要在两个函数之间共享一个公共(public)变量,这不能影响和干扰多线程用例。

#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);
}

最佳答案

如果您有两个需要独立停止的线程,则需要两个循环变量。

在每种情况下,您都需要一个互斥体来保护对共享循环变量的访问,以防止未定义的行为,因为该变量是从两个线程访问的(一个读取它和写它的人)。

在它保护的变量旁边声明你的互斥体:

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};

然后,在访问每个循环变量之前,锁定互斥体,然后解锁互斥体。编写单独的函数来访问循环来封装它可能是最简单的。

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);
}

然后你的entry中的while可以说while(read_loop(&loopvar)),而在exit_loop中你可以编写 write_loop(&loopvar,0) 而不是 loop=0,其中 loopvarloop1适当时循环2

如果您需要在每个线程上运行相同的代码,则可以通过 void* 参数将循环变量的地址传递给该线程。

其他模式可能适用于这种特定情况,但互斥体是用于保护对共享变量的多线程访问的通用工具。

关于c - 在多线程环境中两个函数之间共享公共(public)变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59837184/

相关文章:

检查单向链表是否为回文 C

linux - FreeRadius 到 Cisco ACS

python - Pyserial - 嵌入式系统

php - 来自 Kannel 的空白短信

java - 无法命名后台线程,Void 错误

c++ - 使用多个线程进行 GL 调用是否安全?

c - C 中的嵌套结构

c - C 中空格等于 '\0' 吗?我怎样才能避免混淆它们?

C printf 输出到变量

c - C 中的 Pthread arg