gpt4 book ai didi

c - pthread执行陷入无限循环

转载 作者:行者123 更新时间:2023-11-30 20:08:58 25 4
gpt4 key购买 nike

我正在尝试的是:

  • 创建了四个线程(main创建了3个线程,线程3创建了线程4)
  • 一个共享内存对象在所有线程之间共享。
  • 另一个共享内存对象在线程二和线程四之间共享。
  • 线程 4 等待来自线程 2 的信号,直到创建共享内存对象。
  • 所有这些都是互斥的。

但是我的程序陷入了无限循环。需要解决方案的帮助。

下面是我的源代码:

#include <assert.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h> /* for ftruncate */
#include <sys/mman.h> /* for shm_ and mmap */
#include <sys/stat.h> /* For mode constants */
#include <fcntl.h> /* For O_* constants */

pthread_t T1, T2, T3, T4;

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex3 = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond_one;

int fd;
int *shared_heap;
int *shared_heap2;
int *shared_heap3;
int counter = 0;

//thread one creator func
// *argv is the shared mem obj which is passed while thread is created
void* task1(void *argv) {
int *var = (int*) argv;
pthread_mutex_lock(&mutex);
*var += 1;
pthread_mutex_unlock(&mutex);
return NULL;
}

//thread two creator func
// *argv is the shared mem obj which is passed while thread is created
void* task2(void *argv) {
int *var = (int*) argv;
pthread_mutex_lock(&mutex);
*var += 1;

pthread_mutex_unlock(&mutex);
//another mutex to create another shared mem obj
pthread_mutex_lock(&mutex2);
shared_heap2 = (int *) mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE,MAP_SHARED, fd, 0);
assert(shared_heap2);
counter++;
//signal
if (counter > 0) {
pthread_cond_signal(&cond_one);
printf("signal is sent \n");
}
pthread_mutex_unlock(&mutex2);

return NULL;
}

//thread four creator func
//created from thread three
// *argv is the shared mem obj which is passed while thread is created
void* task4(void *argv) {
int *var = (int*) argv;
pthread_mutex_lock(&mutex);
*var += 1;
pthread_mutex_unlock(&mutex);

pthread_mutex_lock(&mutex2);

//waiting for signal from thread two
while (counter > 0) {
pthread_cond_wait(&cond_one, &mutex2);
printf("waiting for signal. \n");
}

*shared_heap2 = 9;
pthread_mutex_unlock(&mutex2);


return NULL;
}

////thread three creator func
void* task3(void *argv) {
int *var = (int*) argv;
pthread_mutex_lock(&mutex);
*var += 1;
pthread_mutex_unlock(&mutex);

//thread four is create from here
assert(pthread_create(&T4, NULL, &task4, var) == 0);
assert(pthread_join(T4, NULL) == 0);
return NULL;
}

int main(void) {

pthread_cond_init(&cond_one, NULL);
fd = shm_open("test_shared_var_heap_local", O_CREAT | O_RDWR,S_IRUSR | S_IWUSR);
assert(fd != -1);
assert(ftruncate(fd, sizeof(int)) == 0);
shared_heap = (int *) mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE,MAP_SHARED, fd, 0);

assert(shared_heap);

printf("main \n");
//assert(shared_heap);

assert(pthread_create(&T1, NULL, &task1, shared_heap) == 0);

assert(pthread_create(&T2, NULL, &task2, shared_heap) == 0);

assert(pthread_create(&T3, NULL, &task3, shared_heap) == 0);
printf("three \n");

assert(pthread_join(T1, NULL) == 0);
assert(pthread_join(T3, NULL) == 0);
assert(pthread_join(T2, NULL) == 0);

return 0;
}

最佳答案

But my program falls in infinite loop.

你愿意

while (counter > 0) {
pthread_cond_wait(&cond_one, &mutex2);
printf("waiting for signal. \n");
}

但是计数器仅在任务2中设置为1一次,没有理由退出该时间

无论如何,这不是唯一的问题,在 task2mutext2 counter 设置为 1 并发送信号,所以

  • 第一种可能task4在设置为1之前已经完成,信号没用

  • else task2 运行速度更快,并且在 task4 之前获取 mutex2,因此当 task4 将get mutex2 信号已发送,但信号未缓冲,因此它永远不会被 task4 接收

如果您想确保 task2 中受 mutex2 保护的代码在 task4 完成受 mutex2 保护的代码之前执行:

  • counter 仍初始化为 0:int counter = 0;
  • task4 中,当 mutex2 被获取时,只需将 counter 设置为 1 并删除无用的测试 if (counter > 0) 在解锁 mutext2 之前的所有情况下发送信号
  • task2 中,当 mutext2 被获取时,将 while (counter > 0) { 替换为 if (counter == 0) {

这样:

  • 如果task4task2之前获取互斥体2,因为计数器仍然是0task4等待信号(解锁mutext2),task2可以获取mutext2并发送信号并解锁mutext2并且完成后,task4 收到信号(锁定 mutext2),然后解锁 mutext2 并完成
  • 如果task2task4之前获取mutext2,则将counter设置为1并解锁mutext2 em> 并完成,task4 可以获取 mutext2 并且不等待信号,因为 counter 为 1,因此解锁 mutext2> 并完成

关于c - pthread执行陷入无限循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54560918/

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