pthread_create的使用方法

看看下面代码:在 main 函数的 for 循环中创建10个线程;每创建一个线程时都把循环变量 i 的值通过 pthread_create 函数的第四个参数传入线程函数中;但是线程获取的值可能不并不是我们想传入的值。

 

#include <pthread.h>

#include <stdio.h>

 

void * threadFunc( void * pm_iPthreadId )

{

        unsigned int iId = * ( unsigned int * ) pm_iPthreadId;

        printf( "### No.%d pthread start exec; pthread id = %u !\n", iId, pthread_self() );

        time_t iStartTime = time( NULL );

        while(1)

        {

                time_t iTempTime = time( NULL );

                if ( iTempTime - iStartTime > 2 )

                {

                        printf( "$$$ NO.%d pthread cirle exec !\n",  * ( unsigned int * ) pm_iPthreadId );

                        iStartTime = time( NULL );

                }

        }

}

 

int main()

{

        pthread_t * pthreadId;

        pthreadId = new pthread_t[10];

        for( unsigned int i = 0; i < 10; i++ )

        {

                int iRet = pthread_create( pthreadId + i,  NULL, threadFunc, &i );

                if ( iRet == 0 )

                {

                        printf( "@@@ create No.%d pthread success; pthreadId = %u !\n", i, pthreadId + i );

                }

        }

        while(1)

        {

        }

        return 0;

}

 

程序运行结果如下(结果是随机的,每次运行可能都不一样):

 

@@@ create No.0 pthread success; pthreadId = 138174472 !

### No.1 pthread start exec; pthread id = 3076803472 !

### No.1 pthread start exec; pthread id = 3087293328 !

@@@ create No.1 pthread success; pthreadId = 138174476 !

@@@ create No.2 pthread success; pthreadId = 138174480 !

### No.3 pthread start exec; pthread id = 3055823760 !

### No.3 pthread start exec; pthread id = 3066313616 !

@@@ create No.3 pthread success; pthreadId = 138174484 !

### No.4 pthread start exec; pthread id = 3045333904 !

@@@ create No.4 pthread success; pthreadId = 138174488 !

@@@ create No.5 pthread success; pthreadId = 138174492 !

### No.6 pthread start exec; pthread id = 3024354192 !

### No.6 pthread start exec; pthread id = 3034844048 !

@@@ create No.6 pthread success; pthreadId = 138174496 !

@@@ create No.7 pthread success; pthreadId = 138174500 !

### No.8 pthread start exec; pthread id = 3003374480 !

### No.8 pthread start exec; pthread id = 3013864336 !

@@@ create No.8 pthread success; pthreadId = 138174504 !

@@@ create No.9 pthread success; pthreadId = 138174508 !

### No.10 pthread start exec; pthread id = 2992884624 !

$$$ NO.10 pthread cirle exec !

$$$ NO.10 pthread cirle exec !

$$$ NO.10 pthread cirle exec !

$$$ NO.10 pthread cirle exec !

$$$ NO.10 pthread cirle exec !

$$$ NO.10 pthread cirle exec !

$$$ NO.10 pthread cirle exec !

$$$ NO.10 pthread cirle exec !

$$$ NO.10 pthread cirle exec !

$$$ NO.10 pthread cirle exec !

$$$ NO.10 pthread cirle exec !

$$$ NO.10 pthread cirle exec !

$$$ NO.10 pthread cirle exec !

$$$ NO.10 pthread cirle exec !

$$$ NO.10 pthread cirle exec !

 

   从以“###”开头的字符结果可以看出:以“###No.0”、“###No.2”、“###No.5、“###No.7”、“###No.7” 的字符没有;从这可以看出,我们从pthread_create 函数的第四个参数传入的值是不安全的,应该受到安全保护。

 

2:此问题原因

 

   pthread_create 函数是非阻塞函数;会立即返回,主线程不会在创建线程后阻塞到线程函数执行完后返回,导致线程函数获取到循环变量 i 的值被主线程立即改变。

 

3:此问题解决方法

 

利用条件变量的保护,在线程函数中把 pthread_create 第四个参数传入的值保存为局部变量。

 

#include <pthread.h>

#include <stdio.h>

 

 

pthread_cond_t m_Cond;

pthread_mutex_t m_Locker;

 

void * threadFunc( void * pm_iPthreadId )

{

        pthread_mutex_lock(&m_Locker);

        unsigned int iId = * ( unsigned int * ) pm_iPthreadId;

        printf( "### No.%d pthread start exec; pthread id = %u !\n", iId, pthread_self() );

        pthread_cond_signal(&m_Cond);

        pthread_mutex_unlock(&m_Locker);

        time_t iStartTime = time( NULL );

        while(1)

        {

                time_t iTempTime = time( NULL );

                if ( iTempTime - iStartTime > 2 )

                {

                        printf( "$$$ NO.%d pthread cirle exec !\n",  * ( unsigned int * ) pm_iPthreadId );

                        iStartTime = time( NULL );

                }

        }

}

 

int main()

{

        pthread_mutex_init(&m_Locker, NULL);

        pthread_cond_init(&m_Cond, NULL);

        pthread_t * pthreadId;

        pthreadId = new pthread_t[10];

        for( unsigned int i = 0; i < 10; i++ )

        {

                pthread_mutex_lock(&m_Locker);

                int iRet = pthread_create( pthreadId + i,  NULL, threadFunc, &i );

                if ( iRet == 0 )

                {

                        printf( "@@@ create No.%d pthread success; pthreadId = %u !\n", i, pthreadId + i );

                }

                pthread_cond_wait(&m_Cond, &m_Locker);

                pthread_mutex_unlock(&m_Locker);

        }

        while(1)

        {

        }

        return 0;

}

 

上面代码运行结果:

 

@@@ create No.0 pthread success; pthreadId = 147902472 !

### No.0 pthread start exec; pthread id = 3087563664 !

@@@ create No.1 pthread success; pthreadId = 147902476 !

### No.1 pthread start exec; pthread id = 3077073808 !

@@@ create No.2 pthread success; pthreadId = 147902480 !

### No.2 pthread start exec; pthread id = 3066583952 !

@@@ create No.3 pthread success; pthreadId = 147902484 !

### No.3 pthread start exec; pthread id = 3056094096 !

@@@ create No.4 pthread success; pthreadId = 147902488 !

### No.4 pthread start exec; pthread id = 3045604240 !

@@@ create No.5 pthread success; pthreadId = 147902492 !

### No.5 pthread start exec; pthread id = 3035114384 !

@@@ create No.6 pthread success; pthreadId = 147902496 !

### No.6 pthread start exec; pthread id = 3024624528 !

@@@ create No.7 pthread success; pthreadId = 147902500 !

### No.7 pthread start exec; pthread id = 3014134672 !

@@@ create No.8 pthread success; pthreadId = 147902504 !

### No.8 pthread start exec; pthread id = 3003644816 !

@@@ create No.9 pthread success; pthreadId = 147902508 !

### No.9 pthread start exec; pthread id = 2993154960 !

$$$ NO.10 pthread cirle exec !

$$$ NO.10 pthread cirle exec !

$$$ NO.10 pthread cirle exec !

$$$ NO.10 pthread cirle exec !

$$$ NO.10 pthread cirle exec !

$$$ NO.10 pthread cirle exec !

$$$ NO.10 pthread cirle exec !

$$$ NO.10 pthread cirle exec !

$$$ NO.10 pthread cirle exec !

$$$ NO.10 pthread cirle exec !

$$$ NO.10 pthread cirle exec !

$$$ NO.10 pthread cirle exec !

$$$ NO.10 pthread cirle exec !

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值