创建线程时使用临时变量容易出现的问题

来源:互联网 发布:淘宝开店身份验证 编辑:程序博客网 时间:2024/06/13 22:21

今天有点思维短路,看完一段有问题的代码,感觉还很对。代码模型如下:


#include <stdio.h>#include <pthread.h>#include <stdlib.h>#include <unistd.h>typedef struct POINT{        int type ;        int x;         int y;}POINT;POINT * p;void * p_han(void * arg){                int idx = *(int *)arg ;                printf("p_han ------------------ type:%d(x= %d ,y = %d ) \n",p[idx].type,p[idx].x,p[idx].y);}void * p_han1(void * arg){                int idx = *(int *)arg ;                printf("p_han1 ------------------ type:%d(x= %d ,y = %d ) \n",p[idx].type,p[idx].x,p[idx].y);}int hande(int idx){        pthread_t pid ;        if(p[idx].type == 1 )        {                pthread_create( &pid,NULL,p_han,(void *)&idx);        }        else if( p[idx].type == 0)        {                pthread_create( &pid,NULL,p_han1,(void *)&idx);        }}int main(){                p = (POINT *)malloc(sizeof(POINT) * 10);                for(int i = 0 ; i < 10 ;i ++)                {                        p[i].type = i % 2 ;                        p[i].x = i + 1 ;                        p[i].y = i + 2 ;                }                for(int i = 0 ;i < 10 ;i ++)                {                        hande(i);                }                sleep(10);}


编译完成后,程序总是core掉了。

gdb 结果如下:

#0  0x00000000004008dc in p_han (arg=0x7ffff74ad96c) at test1.cxx:1919                      printf("p_han ------------------ type:%d(x= %d ,y = %d ) \n",p[idx].type,p[idx].x,p[idx].y);

看完这个,知道原因在哪块了:在函数hande里,循环创建线程时,使用了函数内的自动变量idx作为线程的入参,线程创建完成后,由于线程调度的无序性,该线程可能没有执行,而此时,idx可能已被操作系统回收了,值已发生变化。将上述的程序改为以下的版本进行验证:


#include <stdio.h>#include <pthread.h>#include <stdlib.h>#include <unistd.h>typedef struct POINT{        int type ;        int x;         int y;}POINT;POINT * p;void * p_han(void * arg){                int idx = *(int *)arg ;                printf("p_han--------------------idx = %d ,&idx = %p \n",idx,arg);                printf("p_han ------------------ type:%d(x= %d ,y = %d ) \n",p[idx].type,p[idx].x,p[idx].y);}void * p_han1(void * arg){                int idx = *(int *)arg ;                printf("p_han1--------------------idx = %d ,&idx = %p \n",idx,arg);                printf("p_han1 ------------------ type:%d(x= %d ,y = %d ) \n",p[idx].type,p[idx].x,p[idx].y);}int hande(int idx){        pthread_t pid ;        printf("hande --------------------idx = %d ,&idx = %p \n",idx,&idx);        if(p[idx].type == 1 )        {                pthread_create( &pid,NULL,p_han,(void *)&idx);        }        else if( p[idx].type == 0)        {                pthread_create( &pid,NULL,p_han1,(void *)&idx);        }}int main(){                p = (POINT *)malloc(sizeof(POINT) * 10);                for(int i = 0 ; i < 10 ;i ++)                {                        p[i].type = i % 2 ;                        p[i].x = i + 1 ;                        p[i].y = i + 2 ;                }                for(int i = 0 ;i < 10 ;i ++)                {                        hande(i);                }                sleep(10);}


执行结果如下:

hande --------------------idx = 0 ,&idx = 0x7fff7139fffc hande --------------------idx = 1 ,&idx = 0x7fff7139fffc hande --------------------idx = 2 ,&idx = 0x7fff7139fffc hande --------------------idx = 3 ,&idx = 0x7fff7139fffc hande --------------------idx = 4 ,&idx = 0x7fff7139fffc hande --------------------idx = 5 ,&idx = 0x7fff7139fffc hande --------------------idx = 6 ,&idx = 0x7fff7139fffc hande --------------------idx = 7 ,&idx = 0x7fff7139fffc hande --------------------idx = 8 ,&idx = 0x7fff7139fffc hande --------------------idx = 9 ,&idx = 0x7fff7139fffc p_han--------------------idx = 32762 ,&idx = 0x7fff7139fffc Segmentation fault (core dumped)

即在hande 执行完毕之后,p_han 线程才开始执行,此时,idx值已被修改,导致程序coredump 。

解决方案是 为每个线程用malloc/new开辟一段内存块,由线程函数内部去释放。





0 0