c - 在多线程环境中的 2 个函数之间共享公共变量
问题描述
我正在编写一个多线程用例,其中循环在entry()
函数中连续运行并在exit_loop()
被调用时结束。在下面的示例中,entry()
使用两个线程调用,并且两个线程的执行在exit_loop()
被调用时结束。
现在我想通过在exit_loop()
第一次调用时只退出一个线程来改变这一点,即entry()
从thread[2]
仍然保持调用的线程仍然可以在exit_loop()
再次调用时终止。为了使这两个线程独立,我可以将其移动static int loop
到本地范围。但是我对在和loop
之间传达状态的方式感到震惊。entry()
exit_loop()
希望在两个函数之间共享一个公共变量,这不能影响和干扰多线程用例。
#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);
}
解决方案
如果您有两个需要独立停止的线程,则需要两个loop
变量。
在每种情况下,您都需要一个互斥锁来保护对共享loop
变量的访问以防止未定义的行为,因为该变量是从两个线程访问的(一个读取它,一个写入它)。
在它保护的变量旁边声明你的互斥锁:
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};
然后,在访问每个loop
变量之前,锁定互斥锁,然后解锁互斥锁。编写单独的函数来访问循环来封装它可能是最简单的。
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);
}
然后你的while
inentry
可以说while(read_loop(&loopvar))
,并且 inexit_loop
你可以写write_loop(&loopvar,0)
而不是loop=0
where loopvar
is eitherloop1
或loop2
as appropriate。
如果您需要在每个线程上运行相同的代码,那么您可以通过void*
参数将循环变量的地址传递给该线程。
其他模式可能适用于这种特定情况,但互斥锁是用于保护对共享变量的多线程访问的通用工具。
推荐阅读
- xamarin - Prism Xamarin OnNavigatedTo 不会执行函数
- reactjs - 如何在 Next JS 中共享 redux state 客户端和 props 服务器端
- php - 是什么导致 Codeigniter 3 中出现“无法使用版本号找到迁移”错误?
- python - 语法错误;令牌:“:数字”,附近:“在:数字”
- java - 如何比较java中相同方法的输入
- c# - 读取按数字行访问的行
- ios - Notification Service Extension 是否需要单独的配置文件?
- sql-server - 按分区估算男性和女性客户
- ruby-on-rails - 如何在 GemFiles 中加载 Figaro ENV 变量?
- javascript - 如何删除字符串中的所有内容,直到 Google Apps 脚本中的窗帘字符