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