《實(shí)驗(yàn)四 同步與互斥 Linux實(shí)驗(yàn)報(bào)告》由會(huì)員分享,可在線(xiàn)閱讀,更多相關(guān)《實(shí)驗(yàn)四 同步與互斥 Linux實(shí)驗(yàn)報(bào)告(10頁(yè)珍藏版)》請(qǐng)?jiān)谘b配圖網(wǎng)上搜索。
1、
實(shí)驗(yàn)四 同步與互斥
【實(shí)驗(yàn)?zāi)康暮鸵蟆?
1、掌握進(jìn)程(線(xiàn)程)的同步與互斥。
2、掌握生產(chǎn)者消費(fèi)者問(wèn)題的實(shí)現(xiàn)方法。
3、掌握多線(xiàn)程編程方法。
【實(shí)驗(yàn)內(nèi)容】
實(shí)現(xiàn)生產(chǎn)者消費(fèi)者問(wèn)題
1、有一個(gè)倉(cāng)庫(kù),生產(chǎn)者負(fù)責(zé)生產(chǎn)產(chǎn)品,并放入倉(cāng)庫(kù),消費(fèi)者會(huì)從倉(cāng)庫(kù)中拿走產(chǎn)品(消費(fèi))。
2、倉(cāng)庫(kù)中每次只能入一個(gè)(生產(chǎn)者或消費(fèi)者)。
3、倉(cāng)庫(kù)中可存放產(chǎn)品的數(shù)量最多10個(gè),當(dāng)倉(cāng)庫(kù)放滿(mǎn)時(shí),生產(chǎn)者不能再放入產(chǎn)品。
4、當(dāng)倉(cāng)庫(kù)空時(shí),消費(fèi)者不能從中取出產(chǎn)品。
5、生產(chǎn)、消費(fèi)速度不同.
【實(shí)驗(yàn)原理】
1、 信號(hào)量mutex提供對(duì)緩沖池訪(fǎng)問(wèn)的互斥要求并初始化為1,信號(hào)量empty和full分別用
2、來(lái)表示空緩沖項(xiàng)和滿(mǎn)緩沖項(xiàng)的個(gè)數(shù),信號(hào)量empty初始化為n,信號(hào)量full初始化為0.
2、定義如下結(jié)構(gòu)及數(shù)據(jù):
定義緩沖區(qū)內(nèi)的數(shù)據(jù)類(lèi)型:typedefintbuffer_item;
緩沖區(qū):buffer_itembuffer[BUFFER_SIZE];
對(duì)緩沖區(qū)操作的變量:intin,out;
信號(hào)量mutex提供了對(duì)緩沖池訪(fǎng)問(wèn)的互斥要求:pthread_mutex_tmutex;
信號(hào)量empty和full分別表示空緩沖頂和滿(mǎn)緩沖頂?shù)膫€(gè)數(shù):sem_tempty,full;
可以設(shè)定生產(chǎn)者的生產(chǎn)速度及消費(fèi)者的消費(fèi)速度:intpro_spe
3、ed,con_speed;
對(duì)緩沖區(qū)操作的自增函數(shù):#defineinc(k)if(k
4、
【程序代碼】
//sx。c
#include
#include〈pthread。h〉
#include〈semaphore。h〉
#include〈time。h〉
#define inc(k) if(k
5、int in,out;//對(duì)緩沖區(qū)操作的變量
pthread_mutex_t mutex;//信號(hào)量mutex提供了對(duì)緩沖池訪(fǎng)問(wèn)的互斥要求
sem_t empty,full;//信號(hào)量empty和full分別表示空緩沖頂和滿(mǎn)緩沖頂?shù)膫€(gè)數(shù)
int pro_speed,con_speed;//可以設(shè)定生產(chǎn)者的生產(chǎn)速度及消費(fèi)者的消費(fèi)速度
int insert_item(buffer_item item)
{//將生產(chǎn)的產(chǎn)品放入緩沖區(qū)
buffer[in]=item;
printf(”******insert緩沖池第%d號(hào)******\n”,in);
inc(in);
}
int
6、remove_item(buffer_item *item)
{//從緩沖區(qū)內(nèi)移走一個(gè)產(chǎn)品
*item = buffer[out];
printf("******remove緩沖池第%d號(hào)******\n",out);
inc(out);
}
void *producer(void *param)
{//生產(chǎn)者進(jìn)程
buffer_item item;
int num = 0;
while(1)
{
sleep(rand()%(16-pro_speed));
printf("\n******第%d次生產(chǎn)******\n”,++num);
printf(”******等
7、待empty信號(hào)******\n");
sem_wait(&empty);
printf(”******等待解鎖******\n”);
pthread_mutex_lock(&mutex);
printf(”******上鎖,準(zhǔn)備生產(chǎn)******\n");
item = rand()%1000+1;
printf(”******生產(chǎn)產(chǎn)品%d*******\n",item);
insert_item(item);
printf(”*******解鎖******\n");
printf("******第%d次生產(chǎn)結(jié)束*******\n\n",num);
pthr
8、ead_mutex_unlock(&mutex);
sem_post(&full);
}
}
void *consumer(void *param)
{//消費(fèi)者進(jìn)程
buffer_item item;
int num = 0;
while(1){
sleep(rand()%(16—con_speed));
printf("\n******第%d次消費(fèi)*****\n",++num);
printf(”******等待full信號(hào)******\n");
sem_wait(&full);
printf(”******等待解鎖******\n");
pthread_mut
9、ex_lock(&mutex);
printf(”******上鎖,準(zhǔn)備消費(fèi)******\n”);
remove_item(&item);
pthread_mutex_unlock(&mutex);
sem_post(&empty);
printf(”******消費(fèi)產(chǎn)品%d*******\n",item);
printf(”*******解鎖******\n");
printf("******第%d次消費(fèi)結(jié)束*******\n\n”,num);
}
}
int main()//主函數(shù)
{
pthread_t tid1,tid2;
pthread_attr
10、_t attr1,attr2;
srand(time(NULL));
pthread_mutex_init(&mutex,NULL);//初始化
sem_init(&empty,0,BUFFER_SIZE);
sem_init(&full,0,0);
in=0;
out=0;
printf("***********************\n”);
printf("********開(kāi)始!***********\n");
printf(”***********************\n");
printf(”生產(chǎn)者速度(1-15):\n");
scanf("%d”,&pr
11、o_speed);
printf(”消費(fèi)者速度(1-15):\n");
scanf("%d",&con_speed);
pthread_attr_init(&attr1);
pthread_create(&tid1,&attr1,producer,NULL);
pthread_attr_init(&attr2);
pthread_create(&tid2,&attr2,consumer,NULL);
sleep(100);
printf(”*******程序over*******\n");
return 0;
}
【實(shí)驗(yàn)步驟】
編寫(xiě)程序代碼gedit sx.c,再對(duì)
12、代碼進(jìn)行編譯gcc sx.c –o sx –lpthread,編譯無(wú)錯(cuò)誤,進(jìn)行運(yùn)行。/sx,根據(jù)提示要求進(jìn)行填寫(xiě)生產(chǎn)者和消費(fèi)速度,觀(guān)察消費(fèi)者和生產(chǎn)者進(jìn)程。
【實(shí)驗(yàn)結(jié)果】
【實(shí)驗(yàn)體會(huì)】
1、Linux中生成線(xiàn)程方法:
第一種方式是用pthread 庫(kù)來(lái)實(shí)現(xiàn)的,是在用戶(hù)程序本身中實(shí)現(xiàn)線(xiàn)程,這實(shí)際上是對(duì)線(xiàn)程的一種模擬,線(xiàn)程之間的切換和調(diào)度是在用戶(hù)的進(jìn)程內(nèi)部進(jìn)行的,這種方式就被稱(chēng)為用戶(hù)空間的線(xiàn)程.
這種線(xiàn)程的好處是實(shí)現(xiàn)非常簡(jiǎn)單,性能也非常好,因?yàn)榫€(xiàn)程之間的切換都在用戶(hù)進(jìn)程內(nèi)部進(jìn)行,切換開(kāi)銷(xiāo)比較小。缺點(diǎn)也非常明顯,首先就是不能充分利用高端系統(tǒng)的
13、SMP多處理器的優(yōu)點(diǎn),因?yàn)橐粋€(gè)進(jìn)程只能由一個(gè)處理器處理,第二點(diǎn)由于用戶(hù)空間是在用戶(hù)空間切換,某個(gè)線(xiàn)程遇到一個(gè)需要阻塞的系統(tǒng)調(diào)用進(jìn)而就會(huì)造成這個(gè)進(jìn)程被阻塞,因而所有線(xiàn)程被阻塞。
第二種方式是通過(guò)修改進(jìn)程的實(shí)現(xiàn)方式來(lái)完成,可以使用不完全的進(jìn)程創(chuàng)建方式創(chuàng)建共享數(shù)據(jù)空間的進(jìn)程,在Linux下這種系統(tǒng)調(diào)用為clone()。
2、Ptrtead生成線(xiàn)程: POSIX thread簡(jiǎn)稱(chēng)為pthread,Posix線(xiàn)程是POSIX標(biāo)準(zhǔn)線(xiàn)程該標(biāo)準(zhǔn)定義內(nèi)部API創(chuàng)建和操縱線(xiàn)程。
數(shù)據(jù)類(lèi)型 pthread_t:
線(xiàn)程句柄 pthread_attr_t:
線(xiàn)程屬性 線(xiàn)程操縱
14、函數(shù)(省略參數(shù)):
pthread_create():創(chuàng)建一個(gè)線(xiàn)程
pthread_exit():終止當(dāng)前線(xiàn)程
pthread_cancel():中斷另外一個(gè)線(xiàn)程的運(yùn)行
pthread_join():阻塞當(dāng)前的線(xiàn)程,直到另外一個(gè)線(xiàn)程運(yùn)行結(jié)束
pthread_attr_init():初始化線(xiàn)程的屬性
pthread_attr_setdetachstate():設(shè)置脫離狀態(tài)的屬性(決定這個(gè)線(xiàn)程在終止時(shí)是否可以被結(jié)合)
pthread_attr_getdetachstate():獲取脫離狀態(tài)的屬性
pthread_attr_destroy():刪除線(xiàn)程的屬性
pthread_kill():向線(xiàn)程發(fā)送一個(gè)信號(hào)