gpt4 book ai didi

c - pthread_mutex_unlock 不是原子的

转载 作者:太空宇宙 更新时间:2023-11-04 03:06:27 24 4
gpt4 key购买 nike

我有以下源代码(改编 self 的原始代码):

#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>

#include "pthread.h"

#define MAX_ENTRY_COUNT 4

int entries = 0;
bool start = false;

bool send_active = false;

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t condNotEmpty = PTHREAD_COND_INITIALIZER;
pthread_cond_t condNotFull = PTHREAD_COND_INITIALIZER;

void send()
{
for (;;) {
if (!start)
continue;
start = false;

for(int i = 0; i < 11; ++i) {
send_active = true;

pthread_mutex_lock(&mutex);
while(entries == MAX_ENTRY_COUNT)
pthread_cond_wait(&condNotFull, &mutex);
entries++;
pthread_cond_broadcast(&condNotEmpty);
pthread_mutex_unlock(&mutex);

send_active = false;
}
}
}

void receive(){
for(int i = 0; i < 11; ++i){
pthread_mutex_lock(&mutex);
while(entries == 0)
pthread_cond_wait(&condNotEmpty, &mutex);
entries--;
pthread_cond_broadcast(&condNotFull);
pthread_mutex_unlock(&mutex);
}

if (send_active)
printf("x");
}

int _tmain(int argc, _TCHAR* argv[])
{
pthread_t s;

pthread_create(&s, NULL, (void *(*)(void*))send, NULL);

for (;;) {
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&condNotEmpty, NULL);
pthread_cond_init(&condNotFull, NULL);

start = true;

receive();

pthread_mutex_destroy(&mutex);
mutex = NULL;
pthread_cond_destroy(&condNotEmpty);
pthread_cond_destroy(&condNotFull);
condNotEmpty = NULL;
condNotFull = NULL;

printf(".");
}

return 0;
}

问题如下:有时发送函数中的最后一个解锁在接收方法继续之前未完成。在我的原始代码中,互斥锁位于一个对象中,该对象在完成工作后被删除。如果发送方法未完成最后一次解锁,则互斥体无效,我的程序会导致解锁失败。

可以通过运行程序轻松重现该行为:每次显示“x”时,接收方法都快完成,发送方法在解锁调用中“挂起”。

我使用 VS2008 和 VS2010 进行了编译 - 两者的结果相同。

pthread_mutex_unlock 不是原子的,这可以解决问题。我该如何解决这个问题?欢迎任何评论...

最好的问候

迈克尔

最佳答案

您的 printf("x") 是教科书上的竞争条件示例。

在 pthread_mutex_unlock() 之后,操作系统可以自由地在任意时间不安排该线程:滴答、秒或天。您不能假设 send_active 会及时“伪造”。

关于c - pthread_mutex_unlock 不是原子的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4387327/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com