并行线程执行下降无限循环

问题描述 投票:-2回答:1

我想做的是:

  • 创建了四个线程(主创建线程3和线程3创建线程4)
  • 一个共享内存对象的所有线程之间共享。
  • 另一个共享存储器对象是线程2和线程4之间共享。
  • 线程信号4个从等待线程2直到创建共享MEM OBJ。
  • 全部是互斥的。

但我的计划落在无限循环。需要帮助的解决方案。

下面是我的源代码:

#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;
}
c pthreads shared-memory
1个回答
2
投票

但我的计划落在无限循环。

你做

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

但柜台正好被设置为1周一次在任务2,没有理由去而走出

反正这不是单独的问题,在TASK2下mutext2计数器设置为1,信号被发送,所以

  • 然后将其设置为1已经完成第一可能性task4,信号是无用
  • 否则TASK2更快运行和task4前获得互斥锁2,所以当task4将获得互斥锁2信号已发送到,但没有缓冲的信号,所以它永远不会被task4接收

如果你想以确保之前task4完成由互斥锁2保护的代码被执行在TASK2互斥锁2保护的代码:

  • 计数器仍在初始化为0:int counter = 0;
  • 在task4当互斥锁2中得到的只是计数器设置为1,删除无用的测试if (counter > 0)在所有情况下发送信号之前解锁mutext2
  • 在TASK2当mutext2是得到更换由while (counter > 0) {if (counter == 0) {

接着就,随即 :

  • 如果task4 TASK2前获得互斥锁2,因为柜台仍然是0 task4等待信号(即解锁mutext2),TASK2可以得到mutext2并发送信号和解锁mutext2和饰面,task4接收信号(即锁mutext2)然后解锁mutext2和完成
  • 如果TASK2获得task4之前计数器设置为1 mutext2和解锁mutext2和饰面,task4可以得到mutext2,不等待信号,因为计数器是1,因此解锁mutext2和完成
© www.soinside.com 2019 - 2024. All rights reserved.