Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.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 pthread_join似乎在修改我的循环索引_C_Multithreading_For Loop_Pthreads_Pthread Join - Fatal编程技术网

C pthread_join似乎在修改我的循环索引

C pthread_join似乎在修改我的循环索引,c,multithreading,for-loop,pthreads,pthread-join,C,Multithreading,For Loop,Pthreads,Pthread Join,我的代码(见下文)产生了一种奇怪的行为。输出为: 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 .

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

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之后我被重置为0。这使我得出这样的结论,修改必须发生在那里的某个地方。但我什么也找不到。我觉得有点傻,因为这不是一段很难的代码。我没有注意到什么

操作系统是Ubuntu 14.04。N_线程当前设置为10,N_运行数为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;
pthread_t threads[N_threads];
pthread_attr_t attr;
int i;
int rc;
智力状态;
printf(“测试是否存在并发问题…”);
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,pthread_CREATE_JOINABLE);
对于(i=0;i
工作线程:

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);
}
void*readStuff(void*a)
{
int i;
对于(i=0;i
除了主线程和上面代码中创建的线程之外,没有其他线程


我认为您的问题在于
pthread\u join
。从手册页:

int pthread_join(pthread_t thread, void **retval); ... If retval is not NULL, then pthread_join() copies the exit status of the tar‐ get thread (i.e., the value that the target thread supplied to pthread_exit(3)) into the location pointed to by *retval. If the target thread was canceled, then PTHREAD_CANCELED is placed in *retval. int pthread_join(pthread_t thread,void**retval); ... 如果retval不为NULL,则pthread_join()复制tar的退出状态 获取线程(即,目标线程提供给的值 pthread_exit(3))进入*retval指向的位置。如果目标 线程被取消,然后PTHREAD_cancelled被放置在*retval中。 请注意,它采用了一个
void**
,这意味着它将用
void*
(大小为8,64位)覆盖
retval
指向的内容。您正在传递一个
int*
(即
&status
),它是指向大多数平台上大小为4的对象的指针

因此,
pthread\u join
将覆盖内存。相反,根据函数原型将
status
声明为
void*

您也在测试
状态
;我不知道你在这里想要实现什么


通常,使用
-Wall
编译会显示这些错误。

连接部分中有两个for循环。这是打字错误吗?提供一个完整的、可编译的示例如何?我在问题上加了一个。在使用石膏时要更加小心
pthread_exit((void*)0)
是不必要的,
pthread_exit(NULL)
pthread_exit(0)
都可以。
pthread\u join
调用是错误的,但是被您的强制转换隐藏了。声明一个
void*
变量并将其地址传递给
pthread\u join
(不带强制转换)以恢复状态。-Wall-Wextra没有通知我这一点。但它解决了问题!谢谢如果我说这不会发生在32位系统上,对吗?是的(我错过了演员阵容)。是的,
sizeof(void*)==sizeof(int)
在32位上。它不会将8个字节写入32位上的4字节内存位置,但您的代码仍然是错误的,因为
pthread\u join
会将地址写入
status