UNIX环境高级编程——pthread_create的问题
? ? ?linux 下常用的創(chuàng)建多線程函數(shù)pthread_create(pthread_t * thread , pthread_attr_t * attr , void *(*start_routine)(void*) , void *args);
其中第一個參數(shù)用來保存線程信息,第二個參數(shù)指新線程的運行屬性,可以設(shè)置為NULL,第三個參數(shù)為自定義的線程函數(shù),第四個參數(shù)就是線程函數(shù)需要用到的參數(shù),一般如果要傳遞多個參數(shù),可以設(shè)置為結(jié)構(gòu)體(struct)類型,這里我們使用int類型的變量。 ?
? ? ?下面我著重討論一個用for結(jié)構(gòu)來創(chuàng)建多個線程時參數(shù)傳遞的問題:
#include <stdio.h> #include <stdlib.h> #include <pthread.h>#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<th_pop; i++){pthread_create(&a_thread[i] , NULL , thread_func , &i);}//wait the end of the threads;for( i=0; i<th_pop; i++){int res = pthread_join(a_thread[i] , NULL);if(res != 0)printf("the thread id: %d ends fail \n",i);}pthread_mutex_destroy(&mutex);}int main() {init();return 0; }
運行結(jié)果:
huangcheng@ubuntu:~$ ./a.out 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看到這個結(jié)果有沒有感覺到有什么不對呢?可能你會感覺到很納悶,怎么出現(xiàn)了那么多的id=0的結(jié)果呢?其實這個認(rèn)真分析一下并不難理解:
首先pthread_create函數(shù)傳遞的是一個指針型的參數(shù),即傳遞的是一個地址而已,這樣在執(zhí)行for結(jié)構(gòu)時:
for(int i=0; i<th_pop; i++) {pthread_create(&a_thread[i] , NULL , thread_func , &i); }
? ? ?該for循環(huán)快速執(zhí)行完成,并且將i置為20,故而傳遞的地址指向的內(nèi)容為20,同時其它的線程還沒來得及執(zhí)行:?int t_id = *(int*)args;
這樣就使得多個線程都指向同一個地址,內(nèi)容為20,解決該問題的一個辦法為中for結(jié)構(gòu)中加入sleep(1),這樣當(dāng)sleep時間大于線程函數(shù)執(zhí)行時間,就可以得到一個正確的結(jié)果,不過這種辦法剝掉了并發(fā)性,并不可取,下面我們采用另一種方法。
我們只修改init()函數(shù)
從這個例子中我們應(yīng)該明白,要避免直接在傳遞的參數(shù)中傳遞發(fā)生改變的量,否則會導(dǎo)致結(jié)果不可測。
解決這類問題的辦法:
(1)復(fù)制一份到堆里面。
(2)加鎖。(一般做法)
(3)用結(jié)構(gòu)體數(shù)組。(推薦這個)
(4)sleep。(不推薦)
轉(zhuǎn)載于:https://www.cnblogs.com/wangfengju/p/6172684.html
總結(jié)
以上是生活随笔為你收集整理的UNIX环境高级编程——pthread_create的问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 美国只有两样东西要比中国 贵,一个是智慧
- 下一篇: 【HDOJ】4602 Partition