資源描述:
《linux多線程編程之同步與互斥實(shí)例講解》由會(huì)員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在教育資源-天天文庫(kù)。
1、linux多線程編程之同步與互斥實(shí)例講解時(shí)間:2013-10-1413:12來(lái)源:武漢華嵌作者:張老師點(diǎn)擊:278次Linux多線程同步與互斥問(wèn)題作者:武漢華嵌教學(xué)部講師張老師一、為什么要用多線程技術(shù)?1.避免阻塞,大家知道,單個(gè)進(jìn)程只有一個(gè)主線程,當(dāng)主線程阻塞的時(shí)候,整個(gè)進(jìn)程也就阻 作者:武漢華嵌教學(xué)部講師張老師一、為什么要用多線程技術(shù)?1.避免阻塞,大家知道,單個(gè)進(jìn)程只有一個(gè)主線程,當(dāng)主線程阻塞的時(shí)候,整個(gè)進(jìn)程也就阻塞了,無(wú)法再去做其它的一些功能了。2.避免CPU空轉(zhuǎn),應(yīng)用程序經(jīng)常會(huì)涉及到RPC,數(shù)
2、據(jù)庫(kù)訪問(wèn),磁盤IO等操作,這些操作的速度比CPU慢很多,而在等待這些響應(yīng)時(shí),CPU卻不能去處理新的請(qǐng)求,導(dǎo)致這種單線程的應(yīng)用程序性能很差。3.提升效率,一個(gè)進(jìn)程要獨(dú)立擁有4GB的虛擬地址空間,而多個(gè)線程可以共享同一地址空間,線程的切換比進(jìn)程的切換要快得多。二、如何使用多線程技術(shù)進(jìn)行編程?首先給一個(gè)完整的多線程程序,以下是最簡(jiǎn)單的模擬火車票售票系統(tǒng):#include#include#include#include#include<
3、unistd.h>void*ticketport1(void*);//線程函數(shù)聲明void*ticketport2(void*);//線程函數(shù)聲明inttickets=100;//火車票的起始值intmain(){pthread_tid1,id2;intret;ret=pthread_create(&id1,NULL,ticketport1,NULL);//創(chuàng)建線程1if(ret<0){perror("creatthread1:");exit(-1);}ret=pthread_create(&id2,NU
4、LL,ticketport2,NULL);//創(chuàng)建線程2if(ret<0){perror("creatthread2:");exit(-1);}pthread_join(id1,NULL);//等待線程1結(jié)束pthread_join(id2,NULL);//等待線程2結(jié)束return0;}void*ticketport1(void*arg){while(1){if(tickets>0){//usleep(1000);//售票點(diǎn)1每賣一張票,自減一printf("ticketport1sellsticket
5、:%d",tickets--);}else{break;}}return(void*)0;}void*ticketport2(void*arg){while(1){if(tickets>0){//usleep(1000);//售票點(diǎn)2每賣一張票,自減一printf("ticketport2sellsticket:%d",tickets--);}else{break;}}return(void*)0;}我們用pthread_create函數(shù)來(lái)創(chuàng)建線程,用pthread_join來(lái)阻塞主線程,等待子線
6、程執(zhí)行完成后返回。利用了多線程技術(shù)來(lái)創(chuàng)建了兩個(gè)售票點(diǎn),可以不同的地方進(jìn)行同時(shí)售票。用gcc帶選項(xiàng)-lpthread來(lái)連結(jié)pthread庫(kù)函數(shù)。執(zhí)行這個(gè)程序發(fā)現(xiàn)兩個(gè)售票點(diǎn)在正常售票,一部分連續(xù)是ticketport1,另一部分連續(xù)是ticketport2;此時(shí),其實(shí)存在一個(gè)隱含的問(wèn)題,就是線程間的切換,在單CPU系統(tǒng)中,CPU是有時(shí)間片時(shí)間,時(shí)間片到了,就要執(zhí)行其它的線程,假設(shè)thread1執(zhí)行到if里面,但在printf執(zhí)行前發(fā)生了線程切換,那么會(huì)發(fā)生什么呢?我們?cè)谶@里用usleep函數(shù)(放開程序中的us
7、leep注釋行)進(jìn)行強(qiáng)制模擬切換,編譯運(yùn)行程序發(fā)現(xiàn)竟然有0號(hào)票被賣出了,這顯然是錯(cuò)誤的!當(dāng)thread1的if里面發(fā)生線程切換時(shí),thread2得到運(yùn)行,把最后一張票賣了,此時(shí)thread1恢復(fù)運(yùn)行,結(jié)果賣出了0號(hào)票,這里我們需要的是火車票的票數(shù)數(shù)據(jù)對(duì)于所有線程而言是同步的,所以就要用到線程同步技術(shù)了。三、使用多線程的同步與互斥1、多線程的同步方式有很多種,例如互斥鎖,條件變量,信號(hào)量,讀寫鎖。先看看互斥鎖如何解決多線程之間的同步問(wèn)題。程序用互斥鎖后如下:#include#include
8、#include#include#includevoid*ticketport1(void*);void*ticketport2(void*);inttickets=100;pthread_mutex_tmutex;intmain(){intret;pthread_tid1,id2;pthread_mutex_init(&mutex,NULL);/