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