zoukankan      html  css  js  c++  java
  • 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
    ", 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
    ",t);
    27                 rc=pthread_create(&threads[t],NULL,(void *)PrintHello, (void *)&t);
    28                 if(rc!=0){
    29                         printf("error. return code is %d
    ", 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。

  • 相关阅读:
    Shell面试题4:扫描网络内存活主机案例
    第三题批量创建特殊要求用户案例
    chpasswd 更简单的更改密码的方式
    30题之第二题
    shell30题之第一题
    2019牛客多校第四场B xor——线段树&&线性基的交
    POJ 2893 M × N Puzzle——八数码有解条件
    2019HDU多校第四场 Just an Old Puzzle ——八数码有解条件
    2019HDU多校第三场F Fansblog——威尔逊定理&&素数密度
    威尔逊定理
  • 原文地址:https://www.cnblogs.com/fallenmoon/p/6769068.html
Copyright © 2011-2022 走看看