pthread_create()的一个错误示例

 

 1 //pthread_create()函数的错误示例
 2 //新建线程同时传入线程号、线程号总和和消息
 3 #include <stdio.h>
 4 #include <pthread.h>
 5 #include <stdlib.h>
 6 #define NUM_THREADS     8
 7 
 8 void *PrintHello(void *threadid)
 9 {
10         int *id_ptr, taskid;
11         sleep(1);
12         id_ptr=(int *)threadid;
13         taskid=*id_ptr;
14         printf("Hello from thread %d\n", taskid);
15         pthread_exit(NULL);
16 }
17 //int t;
18 int main(int argc, char const *argv[])
19 {
20         pthread_t threads[NUM_THREADS];
21         int rc; 
22         int t;
23             
24         for (t = 0; t < NUM_THREADS; ++t)
25         {   
26                 printf("Creating thread %d\n",t);
27                 rc=pthread_create(&threads[t],NULL,(void *)PrintHello, (void *)&t);
28                 if(rc!=0){
29                         printf("error. return code is %d\n", rc);
30                         exit(-1);
31                 }   
32         //      sleep(1);
33 //              pthread_join(threads[t],NULL);
34         }   
35         pthread_exit(NULL);
36 }

在这里主线程创建8个子线程,8个子线程都运行同一个函数PrintHello,休眠1s后打印传入的参数为t

运行结果如下,主线程打印完8条"Creating thread"后经过1s左右子线程打印8条"Hello from thread"

如果取消掉32行或33行的注释,则出现正确的结果:

那为什么会这样呢?先贴一张图

这是函数调用过程图。没错,在对于整个进程来说,主线程生成子线程在由子线程执行某个函数,对CPU来说就是函数调用。从第一次的运行结果可以看出,其执行顺序应该是先主线程执行到pthread_exit()然后等待所有的子线程运行,那这样,有8次参数传递,而且都是存放在同一个地址,即调用者栈帧的ebp+8这个位置,而这个存放的是主线程即main函数栈帧中t的位置。所以,经过一次又一次的覆盖,主线程执行完后最终传递给子线程的应该是最后一次变动后的t。

posted on 2017-04-26 16:00  枝桠  阅读(3236)  评论(0编辑  收藏  举报

导航