在睡眠中穿着C线程

时间:2013-06-01 08:03:20

标签: c linux multithreading pthreads

我正在学习C线程概念,我在下面编写了简单的代码。现在,当我编译并运行它时,我会得到意外打印的随机行为。

#include <pthread.h>
#include <stdio.h>

void * func_threadName(void * i) {

    int *x=(int *)i;
    printf("I'm thread : %d\n",*x);

return NULL;
}
main()
{
    int iter;
    printf("testing multithreading....\n");

    pthread_t thread_arr[3];

    for (iter=0;iter<3;iter++)
    {
        pthread_create(&thread_arr[iter],NULL,func_threadName,&iter);

    }

     for (iter=0;iter<3;iter++)
     {
         pthread_join(thread_arr[iter],NULL);
     }
}

它不可预测地打印如下:

diwakar@diwakar-VPCEH25EN:~/Documents/my_C_codes$ ./thread_test.o 
testing multithreading....
I'm thread : 0
I'm thread : 0
I'm thread : 0
diwakar@diwakar-VPCEH25EN:~/Documents/my_C_codes$ ./thread_test.o 
testing multithreading....
I'm thread : 0
I'm thread : 2
I'm thread : 1
diwakar@diwakar-VPCEH25EN:~/Documents/my_C_codes$ ./thread_test.o 
testing multithreading....
I'm thread : 2
I'm thread : 2
I'm thread : 0

但是当我在创建线程后进行如下所示的微小更改时,它会完美地工作并按顺序打印。

pthread_create(&thread_arr[iter],NULL,func_threadName,&iter);
        sleep(1);

现在每次输出都是这样的:

diwakar@diwakar-VPCEH25EN:~/Documents/my_C_codes$ ./thread_test.o 
testing multithreading....
I'm thread : 0
I'm thread : 1
I'm thread : 2
diwakar@diwakar-VPCEH25EN:~/Documents/my_C_codes$ ./thread_test.o 
testing multithreading....
I'm thread : 0
I'm thread : 1
I'm thread : 2
diwakar@diwakar-VPCEH25EN:~/Documents/my_C_codes$ ./thread_test.o 
testing multithreading....
I'm thread : 0
I'm thread : 1
I'm thread : 2

我想了解在第一种情况下,显示的是不可预测的行为,因为所有线程共享相同的内存空间,因此在一个线程终止之前,其他线程使用相同的i值?欢迎任何其他信息。

3 个答案:

答案 0 :(得分:4)

当线程要运行时,你无法准确判断,因此主线程可以继续,从而在其循环中更改计数器。因为该循环计数器是一个指针,所有线程都有相同的指针指向完全​​相同的变量。您还可以在第二个循环中使用相同的变量,因此可以在线程的生命周期内对其进行两次修改。

将“按原样”传递数字会更好(尽管更“黑客”):

pthread_create(&thread_arr[iter], NULL, func_threadName, (void *) iter);

然后在线程函数中得到它:

int x = (int) i;

答案 1 :(得分:0)

每个线程都应该看到不同的int对象,因此您必须使用第二个数组来管理它。

void * func_threadName(void * i) {

    int *x= i;
    printf("I'm thread : %d\n",*x);

    return NULL;
}

int main(void) {
  printf("testing multithreading....\n");

  pthread_t thread_arr[3];
  int iter_id[3];

  for (int iter=0; iter<3; iter++) {
    iter_id[iter] = iter;
    pthread_create(&thread_arr[iter], NULL, func_threadName, &iter_id[iter]);
  }

  for (iter=0;iter<3;iter++) {
    pthread_join(thread_arr[iter],NULL);
  }
}

同样在C

  • 将其分配给其他数据时,您无需投放void* 指针
  • 所有函数,甚至必须使用返回类型
  • 声明main
  • 应使用(void)
  • 声明和定义不接收参数的函数

答案 2 :(得分:0)

代码的问题在于您传递变量的地址而不是值。因此,所有线程都引用该地址存储的“相同”值。正如Joachim所提到的,这意味着值可能不会足够快地变化,以便新创建的线程获得它。当使用'sleep'时,主线程允许处理器执行其他指令,因此在创建新线程之前更改迭代变量的值。总而言之,您需要传递变量的值而不是Joachim示例中的地址。