c - 提出一个用于原子访问共享内存的包装器
问题描述
我在这里与多线程概念作斗争。
有两个线程访问共享结构。想法是先ThreadTwo
获取锁并设置data
为true,然后运行......如果设置为,ThreadOne
则进入睡眠状态,并在设置为后发出信号后唤醒。data
true
data
false
我所看到的情况:ThreadOne
进入睡眠状态,并且在ThreadTwo
disables之后data
,两个线程似乎都处于死锁状态,或者更确切地说它们被卡住了。
我的理解是:我在结束时解锁互斥锁AccessShm(shmInfo, GET)
,并且我认为pthread_cond_signal
需要已经获得锁,因为它在睡觉前解锁,并且一旦从 发出信号ThreadTwo
,ThreadOne
醒来,获取锁,并尝试再次获取内部AccessShm
但可以不是因为它已经被收购,所以挂起?
typedef enum
{
SET,
GET
} Task;
typedef struct
{
volatile bool data;
pthread_mutex_t pMutex;
pthread_cond_t cv;
} ShmInfo;
bool AccessShm(ShmInfo *pShm, Task t, ...)
{
va_list args;
bool setValue = true;
bool retValue = true;
va_start(args, t);
pthread_mutex_lock(&pShm->pMutex);
switch (t)
{
case SET:
setValue = va_arg(args, bool);
pShm->data = setValue;
if (setValue == false)
{
pthread_cond_signal(&pShm->cv); // wake up only when pShm->data is disabled
}
break;
case GET:
retValue = pShm->data;
break;
default:
break;
}
pthread_mutex_unlock(&pShm->pMutex);
return retValue;
}
void ThreadOne(void *arg)
{
ShmInfo *shmInfo = (ShmInfo *) arg;
while(1)
{
while(AccessShm(shmInfo, GET) == true)
{
pthread_cond_wait(&shmInfo->cv, &shmInfo->pMutex);
}
// ...
}
}
void ThreadTwo(void *arg)
{
ShmInfo *shmInfo = (ShmInfo *) arg;
// ...
AccessShm(shmInfo, SET, true);
// some work/delay
AccessShm(shmInfo, SET, false);
}
解决方案
在调用之前,您没有锁定与条件变量关联的互斥锁pthread_cond_wait()
。
您只能pthread_cond_wait()
在关联互斥锁锁定的情况下调用。
根据POSIXpthread_cond_wait()
文档(我的粗体字):
pthread_cond_timedwait()
andpthread_cond_wait()
函数应阻塞条件变量。应用程序应确保这些函数被mutex
调用线程锁定调用;否则,将导致错误(对于 PTHREAD_MUTEX_ERRORCHECK 和健壮的互斥锁)或未定义的行为(对于其他互斥锁)。...
推荐阅读
- jquery - 猫头鹰轮播在 vite 中不起作用 - 无法读取未定义的属性(读取“fn”)
- azure-devops - 如何在 RTC2GIT 配置文件中填写正确的信息
- java - 如何解决此 ControlEvent 问题
- git-bash - 退出 git bash for windows 后如何保持进程存活?
- python - 如何在 Docker 中复制上一级的所有目录?
- dictionary - Salesforce 太多 soql 101
- html - 如何在网页上存储来自 websocket 的实时数据?
- java - 如何防止 eclipse/jface/swt 应用程序闪烁
- javascript - 如何使用Javascript更改树枝循环中的标题背景
- mongodb - PyMongo 给客户错误的用户信用?