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