pthread_create 参数传递指针问题

pthread_create 参数传递指针问题
2010-11-04 15:52

linux 下常用的创建多线程函数pthread_create(pthread_t * thread , pthread_attr_t * attr , void *(*start_routine)(void*) , void *args);其中第一个参数用来保存线程信息,第二个参数指新线程的运行属性,可以设置为NULL,第三个参数为自定义的线程函数,第四个参数就是线程函数需要用到的参数,一般如果要传递多个参数,可以设置为结构体(struct)类型,这里我们使用int类型的变量。 下面我着重讨论一个用for结构来创建多个线程时参数传递的问题

先看下面的例子,后面附有结果,先不要看,猜测一下会有什么样的输出:

#include<iostream>
#include<pthread.h>
#include<semaphore.h>
using namespace std;

#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;
    cout<<"the id of this thread is "<<t_id<<endl;
    pthread_mutex_unlock(&mutex);    
    return (void*)NULL;
}

void init()
{
    pthread_mutex_init(&mutex, NULL);
    for(int i=0; i<th_pop; i++)
    {
        pthread_create(&a_thread[i] , NULL , thread_func , &i);
    }
    //wait the end of the threads;
    for(int i=0; i<th_pop; i++)
    {
        int res = pthread_join(a_thread[i] , NULL);
        if(res != 0)
            cout<<"the thread id: "<< i<<" ends fail"<<endl;
    }
    pthread_mutex_destroy(&mutex);
    
}

int main()
{
    init();
    return 0;
}

编译运行

g++ -fpermissive args.cc -o args.o -pthread
./args.o

下面是输出结果,由于线程执行的不确定性,可能你执行的时候得到的结果并非如此,这只是一个代表而已

the id of this thread is 2
the id of this thread is 8
the id of this thread is 9
the id of this thread is 9
the id of this thread is 20
the id of this thread is 20
the id of this thread is 20
the id of this thread is 20
the id of this thread is 20
the id of this thread is 20
the id of this thread is 20
the id of this thread is 20
the id of this thread is 20
the id of this thread is 20
the id of this thread is 20
the id of this thread is 20
the id of this thread is 20
the id of this thread is 20
the id of this thread is 20
the id of this thread is 20
看到这个结果有没有感觉到有什么不对呢?可能你会感觉到很纳闷,怎么出现了那么多的id=20的结果呢?其实这个认真分析一下并不难理解:
首先pthread_create函数传递的是一个指针型的参数,即传递的是一个地址而已,这样在执行for结构时
for(int i=0; i<th_pop; i++)
    {
        pthread_create(&a_thread[i] , NULL , thread_func , &i);
    }
该块快速执行完成,并且将i置为20,故而传递的地址指向的内容为20,同时其它的线程还没来得及执行              int t_id = *(int*)args;,这样就使得多个线程都指向同一个地址,内容为20,解决该问题的一个办法为中for结构中加入sleep(1),这样当sleep时间大于线程函数执行时间,就可以得到一个正确的结果,不过这种办法剥掉了并发性,并不可取,下面我们采用另一种方法。
我们只修改init()函数
void init()
{
    pthread_mutex_init(&mutex, NULL);
    int thread_id[th_pop];
    for(int i=0; i<th_pop; i++)
        thread_id[i] = i;
    for(int i=0; i<th_pop; i++)
    {
        int *t = thread_id +i;
        pthread_create(&a_thread[i] , NULL , thread_func , (void*)t);
    }
    //wait the end of the threads;
    for(int i=0; i<th_pop; i++)
    {
        int res = pthread_join(a_thread[i] , NULL);
        if(res != 0)
            cout<<"the thread id: "<< i<<" ends fail"<<endl;
    }
    pthread_mutex_destroy(&mutex);
    
}
下面输出结果
the id of this thread is 0
the id of this thread is 4
the id of this thread is 2
the id of this thread is 5
the id of this thread is 1
the id of this thread is 3
the id of this thread is 6
the id of this thread is 7
the id of this thread is 8
the id of this thread is 9
the id of this thread is 10
the id of this thread is 11
the id of this thread is 12
the id of this thread is 13
the id of this thread is 14
the id of this thread is 15
the id of this thread is 16
the id of this thread is 17
the id of this thread is 18
the id of this thread is 19

从这个例子中我们应该明白,要避免直接在传递的参数中传递发生改变的量,否则会导致结果不可测
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值