《實(shí)驗(yàn)四 同步與互斥 Linux實(shí)驗(yàn)報(bào)告》由會(huì)員分享,可在線閱讀,更多相關(guān)《實(shí)驗(yàn)四 同步與互斥 Linux實(shí)驗(yàn)報(bào)告(10頁珍藏版)》請(qǐng)?jiān)谘b配圖網(wǎng)上搜索。
1、
實(shí)驗(yàn)四 同步與互斥
【實(shí)驗(yàn)?zāi)康暮鸵蟆?
1、掌握進(jìn)程(線程)的同步與互斥。
2、掌握生產(chǎn)者消費(fèi)者問題的實(shí)現(xiàn)方法。
3、掌握多線程編程方法。
【實(shí)驗(yàn)內(nèi)容】
實(shí)現(xiàn)生產(chǎn)者消費(fèi)者問題
1、有一個(gè)倉庫,生產(chǎn)者負(fù)責(zé)生產(chǎn)產(chǎn)品,并放入倉庫,消費(fèi)者會(huì)從倉庫中拿走產(chǎn)品(消費(fèi))。
2、倉庫中每次只能入一個(gè)(生產(chǎn)者或消費(fèi)者)。
3、倉庫中可存放產(chǎn)品的數(shù)量最多10個(gè),當(dāng)倉庫放滿時(shí),生產(chǎn)者不能再放入產(chǎn)品。
4、當(dāng)倉庫空時(shí),消費(fèi)者不能從中取出產(chǎn)品。
5、生產(chǎn)、消費(fèi)速度不同.
【實(shí)驗(yàn)原理】
1、 信號(hào)量mutex提供對(duì)緩沖池訪問的互斥要求并初始化為1,信號(hào)量empty和full分別用
2、來表示空緩沖項(xiàng)和滿緩沖項(xiàng)的個(gè)數(shù),信號(hào)量empty初始化為n,信號(hào)量full初始化為0.
2、定義如下結(jié)構(gòu)及數(shù)據(jù):
定義緩沖區(qū)內(nèi)的數(shù)據(jù)類型:typedefintbuffer_item;
緩沖區(qū):buffer_itembuffer[BUFFER_SIZE];
對(duì)緩沖區(qū)操作的變量:intin,out;
信號(hào)量mutex提供了對(duì)緩沖池訪問的互斥要求:pthread_mutex_tmutex;
信號(hào)量empty和full分別表示空緩沖頂和滿緩沖頂?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ì)緩沖池訪問的互斥要求
sem_t empty,full;//信號(hào)量empty和full分別表示空緩沖頂和滿緩沖頂?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("********開始!***********\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)步驟】
編寫程序代碼gedit sx.c,再對(duì)
12、代碼進(jìn)行編譯gcc sx.c –o sx –lpthread,編譯無錯(cuò)誤,進(jìn)行運(yùn)行。/sx,根據(jù)提示要求進(jìn)行填寫生產(chǎn)者和消費(fèi)速度,觀察消費(fèi)者和生產(chǎn)者進(jìn)程。
【實(shí)驗(yàn)結(jié)果】
【實(shí)驗(yàn)體會(huì)】
1、Linux中生成線程方法:
第一種方式是用pthread 庫來實(shí)現(xiàn)的,是在用戶程序本身中實(shí)現(xiàn)線程,這實(shí)際上是對(duì)線程的一種模擬,線程之間的切換和調(diào)度是在用戶的進(jìn)程內(nèi)部進(jìn)行的,這種方式就被稱為用戶空間的線程.
這種線程的好處是實(shí)現(xiàn)非常簡(jiǎn)單,性能也非常好,因?yàn)榫€程之間的切換都在用戶進(jìn)程內(nèi)部進(jìn)行,切換開銷比較小。缺點(diǎn)也非常明顯,首先就是不能充分利用高端系統(tǒng)的
13、SMP多處理器的優(yōu)點(diǎn),因?yàn)橐粋€(gè)進(jìn)程只能由一個(gè)處理器處理,第二點(diǎn)由于用戶空間是在用戶空間切換,某個(gè)線程遇到一個(gè)需要阻塞的系統(tǒng)調(diào)用進(jìn)而就會(huì)造成這個(gè)進(jìn)程被阻塞,因而所有線程被阻塞。
第二種方式是通過修改進(jìn)程的實(shí)現(xiàn)方式來完成,可以使用不完全的進(jìn)程創(chuàng)建方式創(chuàng)建共享數(shù)據(jù)空間的進(jìn)程,在Linux下這種系統(tǒng)調(diào)用為clone()。
2、Ptrtead生成線程: POSIX thread簡(jiǎn)稱為pthread,Posix線程是POSIX標(biāo)準(zhǔn)線程該標(biāo)準(zhǔn)定義內(nèi)部API創(chuàng)建和操縱線程。
數(shù)據(jù)類型 pthread_t:
線程句柄 pthread_attr_t:
線程屬性 線程操縱
14、函數(shù)(省略參數(shù)):
pthread_create():創(chuàng)建一個(gè)線程
pthread_exit():終止當(dāng)前線程
pthread_cancel():中斷另外一個(gè)線程的運(yùn)行
pthread_join():阻塞當(dāng)前的線程,直到另外一個(gè)線程運(yùn)行結(jié)束
pthread_attr_init():初始化線程的屬性
pthread_attr_setdetachstate():設(shè)置脫離狀態(tài)的屬性(決定這個(gè)線程在終止時(shí)是否可以被結(jié)合)
pthread_attr_getdetachstate():獲取脫離狀態(tài)的屬性
pthread_attr_destroy():刪除線程的屬性
pthread_kill():向線程發(fā)送一個(gè)信號(hào)