C++用pthread_create()创建线程时需要注意的问题

pthread_create()是Linux中创建线程的一种方式。

#include<pthread.h>

int pthread_create(pthread_t *tidp,const pthread_attr_t *attr,(void*)(*start_rtn)(void*) ,void *arg);

//第一个参数为指向线程标识符的指针。
//第二个参数用来设置线程属性。
//第三个参数是线程运行函数的起始地址。
//第四个参数是运行函数的参数。
//pthread_create() 在调用成功完成之后返回零。其他任何返回值都表示出现了错误。

最近在使用时需要用到呢多线程,所以就用for语句循环创建了多个线程,但是出现了一些问题,特此记录下。

我一开始是这样是这样写的:

pthread_t *pt=(pthread_t*)malloc(num_threads*sizeof(pthread_t));
for(int a=0;a<num_threads;a++)
    pthread_create(&pt[a],NULL,function,&a);
for(int a=0;a<num_threads;a++)
    pthread_join(pt[a],NULL);

我创建线程时是需要把a传入函数function中的,但是,这样会出现混乱,比如,我们需要往第0个线程传入参数0,实际上运行结果显示传入第0个线程的参数不是0。

在网上查了一下,大概问题就是,CPU运行速度很快,而pthread_create()创建线程要有一定的时间,在pthread_create()创建线程再去按照之前参数a的地址去取a时,循环中a的值已经发生了变化,这就造成传入函数function的参数值不对。

既然这样,我就让主线程循环时等一下pthread_create()不就ok了,于是代码变成下面这样:

pthread_t *pt=(pthread_t*)malloc(num_threads*sizeof(pthread_t));
for(int a=0;a<num_threads;a++)
{
    pthread_create(&pt[a],NULL,function,&a);
    sleep(1);  //#include<unistd.h>
}
for(int a=0;a<num_threads;a++)
    pthread_join(pt[a],NULL);

循环时主线程挂起1秒钟,pthread_create()就创建线程完毕了,但这样带来的问题就是:我们使用多线程的初衷就是并行运算、提升效率,但每创建一个线程就能停1秒,如果我们创建线程的次数比较多,那将大大影响程序的整体运行效率。而我试了一下,如果将sleep(1)改成usleep(1000),即睡眠1000微秒(1毫秒),仍可能出现错误。

在网上查了下,通过实践,发现以下两种方法可以解决:

1、实现开辟一块空间存储创建多线程时所需要传入的参数,这样每个线程的参数的地址就不会乱套。

2、在循环创建线程时,我们不直接把循环的控制变量(如上例中的a)直接传入多线程的函数中,我们另外申请一块空间,存储在这块空间上,到时再从这块空间取值就行了。

两种方法的解决方法如下:

//第一种方法

pthread_t *pt=(pthread_t*)malloc(num_threads*sizeof(pthread_t));
int order[num_threads];
for(int a=0;a<num_threads;a++)
    order[a]=a;
for(int a=0;a<num_threads;a++)
    pthread_create(&pt[a],NULL,function,&order[a]);
for(int a=0;a<num_threads;a++)
    pthread_join(pt[a],NULL);


//第二种方法
pthread_t *pt=(pthread_t*)malloc(num_threads*sizeof(pthread_t));
for(int a=0;a<num_threads;a++)
{
    int* temp=(int*)malloc(sizeof(int));
    *temp=a;
    pthread_create(&pt[a],NULL,function,(void*)temp);
}
for(int a=0;a<num_threads;a++)
    pthread_join(pt[a],NULL);

两种效果方法差不多,但是第二种方法使用malloc申请了动态内存,而且还没有释放,所以不是太好。


我疑惑的是,在一些地方,如下的代码竟然能跑,而且完全没问题。。。?(感觉和我写的一模一样啊= - =)我也没搞懂没什么,真的很奇怪。欢迎懂得大佬们留言我。

pthread_t *pt=(pthread_t *)malloc(num_threads*sizeof(pthread_t));
for (int a=0;a <num_threads;a++)
    pthread_create(&pt[a],NULL,function, &a);
for (int a= 0;a<num_threads;a++)
    pthread_join(pt[a],NULL);

参考:

1、https://blog.csdn.net/jfkidear/article/details/7918425

2、https://www.cnblogs.com/love-DanDan/p/8724245.html

3、https://blog.csdn.net/qq_29542611/article/details/79662018

4、https://blog.csdn.net/MonroeD/article/details/60468294

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值