博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UNIX环境高级编程——pthread_create的问题
阅读量:6861 次
发布时间:2019-06-26

本文共 2778 字,大约阅读时间需要 9 分钟。

     linux 下常用的创建多线程函数pthread_create(pthread_t * thread , pthread_attr_t * attr , void *(*start_routine)(void*) , void *args);

其中第一个参数用来保存线程信息,第二个参数指新线程的运行属性,可以设置为NULL,第三个参数为自定义的线程函数,第四个参数就是线程函数需要用到的参数,一般如果要传递多个参数,可以设置为结构体(struct)类型,这里我们使用int类型的变量。  

     下面我着重讨论一个用for结构来创建多个线程时参数传递的问题:

#include 
#include
#include
#define th_pop 20 pthread_mutex_t mutex;pthread_t a_thread[th_pop];void * thread_func(void *args){ pthread_mutex_lock(&mutex); int t_id = *(int*)args; printf("the id of this thread is %d\n",t_id); pthread_mutex_unlock(&mutex); return (void*)NULL;}void init(){ pthread_mutex_init(&mutex, NULL); int i; for( i=0; i

运行结果:

huangcheng@ubuntu:~$ ./a.outthe id of this thread is 2the id of this thread is 8the id of this thread is 9the id of this thread is 9the id of this thread is 20the id of this thread is 20the id of this thread is 20the id of this thread is 20the id of this thread is 20the id of this thread is 20the id of this thread is 20the id of this thread is 20the id of this thread is 20the id of this thread is 20the id of this thread is 20the id of this thread is 20the id of this thread is 20the id of this thread is 20the id of this thread is 20the id of this thread is 20

看到这个结果有没有感觉到有什么不对呢?可能你会感觉到很纳闷,怎么出现了那么多的id=0的结果呢?其实这个认真分析一下并不难理解:

首先pthread_create函数传递的是一个指针型的参数,即传递的是一个地址而已,这样在执行for结构时:

for(int i=0; i

     该for循环快速执行完成,并且将i置为20,故而传递的地址指向的内容为20,同时其它的线程还没来得及执行: int t_id = *(int*)args;

这样就使得多个线程都指向同一个地址,内容为20,解决该问题的一个办法为中for结构中加入sleep(1),这样当sleep时间大于线程函数执行时间,就可以得到一个正确的结果,不过这种办法剥掉了并发性,并不可取,下面我们采用另一种方法。

我们只修改init()函数

#include 
#include
#include
#define th_pop 20 //pthread_mutex_t mutex;pthread_t a_thread[th_pop];void * thread_func(void *args){ pthread_mutex_lock(&mutex); int t_id = *(int*)args; printf("the id of this thread is %d\n",t_id); pthread_mutex_unlock(&mutex); return (void*)NULL;}void init(){ pthread_mutex_init(&mutex, NULL); int thread_id[th_pop]; int i; for( i=0; i
运行结果:

huangcheng@ubuntu:~$ ./a.outthe id of this thread is 3the id of this thread is 2the id of this thread is 1the id of this thread is 4the id of this thread is 5the id of this thread is 6the id of this thread is 7the id of this thread is 8the id of this thread is 9the id of this thread is 10the id of this thread is 11the id of this thread is 12the id of this thread is 13the id of this thread is 14the id of this thread is 15the id of this thread is 16the id of this thread is 17the id of this thread is 18the id of this thread is 19the id of this thread is 0
从这个例子中我们应该明白,要避免直接在传递的参数中传递发生改变的量,否则会导致结果不可测。

解决这类问题的办法:

(1)复制一份到堆里面。
(2)加锁。(一般做法)
(3)用结构体数组。(推荐这个)
(4)sleep。(不推荐)

转载于:https://www.cnblogs.com/hehehaha/p/6332653.html

你可能感兴趣的文章
BZOJ5343[Ctsc2018]混合果汁——主席树+二分答案
查看>>
linux 如何降低入向收包软中断占比
查看>>
小知识点(不定更新)
查看>>
css绝对定位中的初始包含块问题
查看>>
智能指针
查看>>
phpcms导航栏多个栏目调用
查看>>
人脸识别 参考 转盒子
查看>>
SDUT OJ 顺序表应用2:多余元素删除之建表算法
查看>>
CSS
查看>>
Android笔记之为TextView设置边框
查看>>
【Lift】Scala Web 框架——Lift(一)准备工作
查看>>
【转载】增强学习(Reinforcement Learning and Control)
查看>>
GNU使用find命令
查看>>
java的执行与加载的过程
查看>>
8.2 sikuli 集成进eclipse 报错:Getting the VisionProxy.dll: Can not find dependent libraries......
查看>>
2.6.1 XML配置:创建XML文件
查看>>
第六天-数据分类型
查看>>
排版类
查看>>
Java中如何遍历Map对象
查看>>
iOS开发的技能树
查看>>