1

我的代码(见下文)产生了奇怪的行为。输出是:

Testing whether there are problems with concurrency ...rc is 0. i is 0
.rc is 0. i is 0
.rc is 3. i is 1
.rc is 0. i is 0
.rc is 3. i is 1
.rc is 3. i is 2
.rc is 0. i is 0
.rc is 3. i is 1
.rc is 3. i is 2
.rc is 3. i is 3
.rc is 0. i is 0
.rc is 3. i is 1
.rc is 3. i is 2
.rc is 3. i is 3
.rc is 3. i is 4
.rc is 0. i is 0
Segmentation fault (core dumped)

我试图调试它,但只发现在 pthread_join 之后 i 被重置为 0。这使我得出结论,修改必须发生在某个地方。但我找不到东西。我觉得有点愚蠢,因为这并不是一段很难的代码。我没有注意到什么?

操作系统是 Ubuntu 14.04。N_THREADS 当前设置为 10,N_RUNS 为 10000。

主线程:

pthread_t threads[N_THREADS];
pthread_attr_t attr;
int i;
int rc;
int status;

printf("Testing whether there are problems with concurrency ...");

pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

for (i = 0; i < N_THREADS; i++){
  if (i) {
    rc = pthread_create(&(threads[i]), &attr, addRemove, 0);
  } else {
    rc = pthread_create(&(threads[i]), &attr, readStuff, 0);
  }
  if (rc) return rc;
}

for(i = 0; i < N_THREADS; i++) {
  rc = pthread_join(threads[i], (void*) &status);
//  if(rc == 3) 
      printf("rc is %d. i is %d\n", rc, i);
//  if (rc) return rc;
  if (status) return status;
  printf(".");
}

pthread_attr_destroy(&attr);

return 0;

工作线程:

void* readStuff(void* a)
{
  int i;
  for (i = 0; i< N_RUNS; i++){
  ;
  }
  pthread_exit((void*)0);
}

void* addRemove(void* a)
{
   int i;
   for (i = 0; i< N_RUNS; i++){
   ;
   }
   pthread_exit((void*)0);
}

除了主线程和上面代码中创建的线程之外,没有其他线程。

可编译的例子

4

1 回答 1

2

我认为您的问题在于pthread_join. 从手册页:

       int pthread_join(pthread_t thread, void **retval);
       ...

       如果 retval 不为 NULL,则 pthread_join() 复制 tar- 的退出状态
       获取线程(即目标线程提供给的值
       pthread_exit(3)) 进入 *retval 指向的位置。如果目标
       线程被取消,然后 PTHREAD_CANCELED 被放置在 *retval 中。

请注意,它需要 a ,这意味着它用 a (大小为 8,64 位)void **覆盖指向的事物。您正在传递一个(ie ),它是一个指向大多数平台上大小为 4 的对象的指针。retvalvoid *int *&status

所以,pthread_join会覆盖内存。相反,根据函数原型声明status为 a 。void *

你也在测试status;我不知道你想在这里实现什么。

一般来说,编译-Wall会显示这些错误。

于 2015-02-11T09:23:13.643 回答