Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C POSIX螺纹';s互斥锁/条件根据变量所在位置的不同而不同_C_Multithreading_Posix_Mutex - Fatal编程技术网

C POSIX螺纹';s互斥锁/条件根据变量所在位置的不同而不同

C POSIX螺纹';s互斥锁/条件根据变量所在位置的不同而不同,c,multithreading,posix,mutex,C,Multithreading,Posix,Mutex,我在C POSIX线程中看到了互斥体/条件的意外行为,这取决于互斥体和条件变量是否在结构的全局作用域(有时有效)中设置 我在Mac上编程,然后在Linux机器上运行相同的代码。我复制了这个示例中的代码,它在两台机器中都能正常工作: 此示例在全局范围内具有pthread\u mutex\t和pthread\u cond\t: pthread_cond_t cond = PTHREAD_COND_INITIALIZER; pthread_mutex_t mutex = PTHRE

我在C POSIX线程中看到了互斥体/条件的意外行为,这取决于互斥体和条件变量是否在结构的全局作用域(有时有效)中设置

我在Mac上编程,然后在Linux机器上运行相同的代码。我复制了这个示例中的代码,它在两台机器中都能正常工作: 此示例在全局范围内具有
pthread\u mutex\t
pthread\u cond\t

pthread_cond_t      cond  = PTHREAD_COND_INITIALIZER;
pthread_mutex_t     mutex = PTHREAD_MUTEX_INITIALIZER;
...
pthread_mutex_lock(&mutex);
...
但是,如果我将其更改为将cond和mutex存储在一个struct中,它在Mac上工作,但在Linux上不工作

以下是我所做更改的概述:

typedef struct _test_data_t {
  pthread_mutex_t cond;
  pthread_cond_t mutex;
} test_data_t;
...
pthread_mutex_lock(&(test_data->mutex));
...
这是我在Mac上得到的输出(可以正常工作)

创建5个线程 螺纹堵塞 螺纹堵塞 螺纹堵塞 螺纹堵塞 螺纹堵塞 唤醒所有等待的线程。。。 等待线程和清理 主要完成 以下是Linux上的输出(不工作)

创建5个线程 线程阻塞//永远挂在这里,其他线程无法锁定互斥锁 有人知道为什么会这样吗?我承认我不是C专家,所以我不知道从使用全局变量到结构变量的转换会发生什么

提前感谢你的帮助


以下是代码(为了简洁起见,去掉了一些错误检查):

typedef结构测试数据{
int-conditionMet;
pthread_mutex_t cond;
pthread_cond_t mutex;
}测试数据;
void*threadfunc(void*parm)
{
int rc;
测试数据*测试数据=(测试数据*参数);
rc=pthread_mutex_lock((pthread_mutex_t*)&(test_data->mutex));
而(!测试数据->条件满足){
printf(“线程阻塞\n”);
rc=pthread\u cond\u wait(&test\u data->cond,&test\u data->mutex);
}
rc=pthread\u mutex\u unlock(&test\u data->mutex);
返回NULL;
}
void runThreadTest(){
int=5;
int rc=0;
int i;
//初始化互斥锁/条件。
测试数据测试数据;
test_data.conditionMet=0;
rc=pthread\u mutex\u init(&test\u data.mutex,NULL);
rc=pthread_cond_init(&test_data.cond,NULL);
//创建线程。
pthread_t threadid[NTHREADS];
printf(“创建%d个线程\n”,n个线程);

对于(i=0;i而言,问题在于名为
mutex
的成员是
pthread\u cond\u t
,名为
cond
的成员是
pthread\u mutex\u t
。不必要的强制转换可能隐藏了这一事实

typedef struct _test_data_t {
  int conditionMet;
  pthread_mutex_t cond; // <-- poorly named
  pthread_cond_t mutex; // <-- poorly named
} test_data_t;

但是,有几个调用没有强制转换(因此编译器应该大声抱怨)。我开始认为这可能是一个错字,这是一个令人费解的问题。

哇,接得好!我很惊讶类型系统没有阻止这一点。如果它没有被明确覆盖的话,它本来会被覆盖的。哦,天哪,真是太尴尬了。我很惊讶它在我的Mac电脑上工作。谢谢!@something\u或\u nothing:有时会发生在每个人身上,有时也会发生另外,这是只有其他人才会注意到的事情。我更好奇的是,为什么不使用强制类型转换的调用没有编译失败?有一些警告,但我忽略了它们,我想我应该更加注意它们。我在C语言方面的经验不足让我相信我看到的许多警告可以安全地忽略,我想不是真的 Create 5 threads Thread blocked // Hangs here forever, other threads can't lock mutex
typedef struct _test_data_t {
  int conditionMet;
  pthread_mutex_t cond;
  pthread_cond_t mutex;
} test_data_t;

void *threadfunc(void *parm)
{
  int           rc;
  test_data_t *test_data = (test_data_t *) parm;

  rc = pthread_mutex_lock((pthread_mutex_t *)&(test_data->mutex));

  while (!test_data->conditionMet) {
    printf("Thread blocked\n");
    rc = pthread_cond_wait(&test_data->cond, &test_data->mutex);
  }

  rc = pthread_mutex_unlock(&test_data->mutex);
  return NULL;
}

void runThreadTest() {

  int NTHREADS = 5;

  int                   rc=0;
  int                   i;

  // Initialize mutex/condition.
  test_data_t test_data;
  test_data.conditionMet = 0;
  rc = pthread_mutex_init(&test_data.mutex, NULL);
  rc = pthread_cond_init(&test_data.cond, NULL);

  // Create threads.
  pthread_t             threadid[NTHREADS];

  printf("Create %d threads\n", NTHREADS);
  for(i=0; i<NTHREADS; ++i) {
    rc = pthread_create(&threadid[i], NULL, threadfunc, &test_data);
  }

  sleep(5);
  rc = pthread_mutex_lock(&test_data.mutex);

  /* The condition has occurred. Set the flag and wake up any waiting threads */
  test_data.conditionMet = 1;
  printf("Wake up all waiting threads...\n");
  rc = pthread_cond_broadcast(&test_data.cond);

  rc = pthread_mutex_unlock(&test_data.mutex);

  printf("Wait for threads and cleanup\n");
  for (i=0; i<NTHREADS; ++i) {
    rc = pthread_join(threadid[i], NULL);
  }

  pthread_cond_destroy(&test_data.cond);
  pthread_mutex_destroy(&test_data.mutex);

  printf("Main completed\n");
}
typedef struct _test_data_t {
  int conditionMet;
  pthread_mutex_t cond; // <-- poorly named
  pthread_cond_t mutex; // <-- poorly named
} test_data_t;
  rc = pthread_mutex_lock((pthread_mutex_t *)&(test_data->mutex));