實(shí)驗(yàn)二多線程應(yīng)用程序設(shè)計(jì)_第1頁(yè)
實(shí)驗(yàn)二多線程應(yīng)用程序設(shè)計(jì)_第2頁(yè)
實(shí)驗(yàn)二多線程應(yīng)用程序設(shè)計(jì)_第3頁(yè)
實(shí)驗(yàn)二多線程應(yīng)用程序設(shè)計(jì)_第4頁(yè)
實(shí)驗(yàn)二多線程應(yīng)用程序設(shè)計(jì)_第5頁(yè)
已閱讀5頁(yè),還剩1頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

..成績(jī)信息與通信工程學(xué)院實(shí)驗(yàn)報(bào)告課程名稱:嵌入式系統(tǒng)原理與應(yīng)用實(shí)驗(yàn)題目:多線程應(yīng)用程序設(shè)計(jì)指導(dǎo)教師:班級(jí):學(xué)號(hào):學(xué)生:實(shí)驗(yàn)?zāi)康暮腿蝿?wù)掌握VI編譯環(huán)境。掌握GCC編譯命令。掌握多個(gè)文件共同編譯方法。掌握GDB調(diào)試命令。學(xué)習(xí)實(shí)驗(yàn)設(shè)備實(shí)驗(yàn)容及原理實(shí)驗(yàn)步驟或程序流程Gcc編譯實(shí)驗(yàn)編寫(xiě)實(shí)驗(yàn)代碼:圖3.1實(shí)驗(yàn)主程序圖3.2實(shí)驗(yàn)子程序編寫(xiě)Makefile文件:圖3.3Makefile文件Make執(zhí)行Makefile文件,生成可執(zhí)行程序并運(yùn)行:圖3.4執(zhí)行Gdb調(diào)試運(yùn)行:圖3.5gdb調(diào)試顯示代碼圖3.6gdb調(diào)試斷點(diǎn)運(yùn)行圖3.7gdb調(diào)試逐步運(yùn)行多線程程序設(shè)計(jì):對(duì)實(shí)驗(yàn)代碼進(jìn)展gcc編譯:圖3.7gcc編譯生成可執(zhí)行文件運(yùn)行結(jié)果:圖3.8程序運(yùn)行結(jié)果實(shí)驗(yàn)數(shù)據(jù)及程序代碼Gcc編譯實(shí)驗(yàn):主程序:#include"stdio.h"#include"my2.h"intmain(){ printf("hello.Linuxworld.Iam1405014232zzm\n"); my2();}實(shí)驗(yàn)子程序:#include"my2.h"#include"stdio.h"voidmy2(){ inti=1;floats=1 intN; printf("Pleaseinputn:\n"); scanf("%d",&N); for(i,i<=n,i++) s*=i; printf("result:"); printf("%f",s);}.h頭文件:#ifndef_MY2_H#define_MY2_Hintmain();voidmy2();#endifmakefile執(zhí)行文件:zzmgo:my2.omy1.o gcc-ozzmgomy2.omy1.omy1.o:my1.cmy2.h gcc-cmy1.cmy2.o:my2.cmy2.h gcc-cmy2.cclean:rm-rfmy1.omy2.ozzmgo多線程程序設(shè)計(jì):..#include<stdio.h>#include<stdlib.h>#include<time.h>#include"pthread.h"#defineBUFFER_SIZE16/*Circularbufferofintegers.*/structprodcons{intbuffer[BUFFER_SIZE];/*theactualdata*/pthread_mutex_tlock;/*mutexensuringexclusiveaccesstobuffer*/intreadpos,writepos;/*positionsforreadingandwriting*/pthread_cond_tnotempty;/*signaledwhenbufferisnotempty*/pthread_cond_tnotfull;/*signaledwhenbufferisnotfull*/};/*--------------------------------------------------------*//*Initializeabuffer*/voidinit(structprodcons*b){pthread_mutex_init(&b->lock,NULL);pthread_cond_init(&b->notempty,NULL);pthread_cond_init(&b->notfull,NULL);b->readpos=0;b->writepos=0;}/*--------------------------------------------------------*//*Storeanintegerinthebuffer*/voidput(structprodcons*b,intdata){ pthread_mutex_lock(&b->lock); /*Waituntilbufferisnotfull*/ while((b->writepos+1)%BUFFER_SIZE==b->readpos){ printf("waitfornotfull\n"); pthread_cond_wait(&b->notfull,&b->lock); }/*Writethedataandadvancewritepointer*/ b->buffer[b->writepos]=data; b->writepos++; if(b->writepos>=BUFFER_SIZE)b->writepos=0;/*Signalthatthebufferisnownotempty*/ pthread_cond_signal(&b->notempty); pthread_mutex_unlock(&b->lock);}/*--------------------------------------------------------*//*Readandremoveanintegerfromthebuffer*/intget(structprodcons*b){ intdata; pthread_mutex_lock(&b->lock); /*Waituntilbufferisnotempty*/ while(b->writepos==b->readpos){ printf("waitfornotempty\n"); pthread_cond_wait(&b->notempty,&b->lock); } /*Readthedataandadvancereadpointer*/ data=b->buffer[b->readpos]; b->readpos++; if(b->readpos>=BUFFER_SIZE)b->readpos=0; /*Signalthatthebufferisnownotfull*/ pthread_cond_signal(&b->notfull); pthread_mutex_unlock(&b->lock); returndata;}/*--------------------------------------------------------*/#defineOVER(-1)structprodconsbuffer;/*--------------------------------------------------------*/void*producer(void*data){ intn; for(n=0;n<1000;n++){ printf("put-->%d\n",n); put(&buffer,n); }put(&buffer,OVER);printf("producerstopped!\n");returnNULL;}/*--------------------------------------------------------*/void*consumer(void*data){intd;while(1){d=get(&buffer);if(d==OVER)break;printf("%d-->get\n",d);}printf("consumerstopped!\n");returnNULL;}/*--------------------------------------------------------*/intmain(void){ pthread_tth_a,th_b; void*retval; init(&buffer); pthread_create(&th_a,NULL,producer,0); pthread_create(&th_b,NULL,consumer,0);/*Waituntilproducerandconsumerfinish.*/ pthread_join(th_a,&retval); pthread_join(th_b,&retval); return0;}..實(shí)驗(yàn)數(shù)據(jù)分析及處理實(shí)驗(yàn)構(gòu)造流程圖:本實(shí)驗(yàn)為著名的生產(chǎn)者-消費(fèi)者問(wèn)題模型的實(shí)現(xiàn),主程序中分別啟動(dòng)生產(chǎn)者線程和消費(fèi)者線程。生產(chǎn)者線程不斷順序地將0到1000的數(shù)字寫(xiě)入共享的循環(huán)緩沖區(qū),同時(shí)消費(fèi)者線程不斷地從共享的循環(huán)緩沖區(qū)讀取數(shù)據(jù)。流程圖如下圖:圖6.1生產(chǎn)者-消費(fèi)者實(shí)驗(yàn)源代碼構(gòu)造流程圖主要函數(shù)分析:下面我們來(lái)看一下,生產(chǎn)者寫(xiě)入緩沖區(qū)和消費(fèi)者從緩沖區(qū)讀數(shù)的具體流程,生產(chǎn)者首先要獲得互斥鎖,并且判斷寫(xiě)指針+1后是否等于讀指針,如果相等那么進(jìn)入等待狀態(tài),等候條件變量notfull;如果不等那么向緩沖區(qū)中寫(xiě)一個(gè)整數(shù),并且設(shè)置條件變量為notempty,最后釋放互斥鎖。消費(fèi)者線程與生產(chǎn)者線程類似,這里就不再過(guò)多介紹了。流程圖如下:圖6.2生產(chǎn)消費(fèi)流程圖主要的多線程API:在本程序的代碼量的使用了線程函數(shù),如pthread_cond_signal、pthread_mutex_init、pthread_mutex_lock等等,這些函數(shù)的作用是什么,在哪里定義的,我們將在下面的容中為其中比擬重要的函數(shù)做一些詳細(xì)的說(shuō)明。pthread_create線程創(chuàng)立函數(shù):intpthread_create(pthread_t*thread_id,__constpthread_attr_t*__attr,void*(*__start_routine)(void*),void*__restrict__arg)線程創(chuàng)立函數(shù)第一個(gè)參數(shù)為指向線程標(biāo)識(shí)符的指針,第二個(gè)參數(shù)用來(lái)設(shè)置線程屬性,第三個(gè)參數(shù)是線程運(yùn)行函數(shù)的起始地址,最后一個(gè)參數(shù)是運(yùn)行函數(shù)的參數(shù)。這里,我們的函數(shù)thread不需要參數(shù),所以最后一個(gè)參數(shù)設(shè)為空指針。第二個(gè)參數(shù)我們也設(shè)為空指針,這樣將生成默認(rèn)屬性的線程。當(dāng)創(chuàng)立線程成功時(shí),函數(shù)返回0,假設(shè)不為0那么說(shuō)明創(chuàng)立線程失敗,常見(jiàn)的錯(cuò)誤返回代碼為EAGAIN和EINVAL。前者表示系統(tǒng)限制創(chuàng)立新的線程,例如線程數(shù)目過(guò)多了;后者表示第二個(gè)參數(shù)代表的線程屬性值非法。創(chuàng)立線程成功后,新創(chuàng)立的線程那么運(yùn)行參數(shù)三和參數(shù)四確定的函數(shù),原來(lái)的線程那么繼續(xù)運(yùn)行下一行代碼。pthread_join函數(shù)用來(lái)等待一個(gè)線程的完畢。函數(shù)原型為:intpthread_join(pthread_t__th,void**__thread_return)第一個(gè)參數(shù)為被等待的線程標(biāo)識(shí)符,第二個(gè)參數(shù)為一個(gè)用戶定義的指針,它可以用來(lái)存儲(chǔ)被等待線程的返回值。這個(gè)函數(shù)是一個(gè)線程阻塞的函數(shù),調(diào)用它的函數(shù)將一直等待到被等待的線程完畢為止,當(dāng)函數(shù)返回時(shí),被等待線程的資源被收回。pthread_exit函數(shù):一個(gè)線程的完畢有兩種途徑,一種是象我們上面的例子一樣,函數(shù)完畢了,調(diào)用它的線程也就完畢了;另一種方式是通過(guò)函數(shù)pthread_exit來(lái)實(shí)現(xiàn)。它的函數(shù)原型為:voidpthread_exit(void*__retval)唯一的參數(shù)是函數(shù)的返回代碼,只要pthread_join中的第二個(gè)參數(shù)thread_return不是NULL,這個(gè)值將被傳遞給thread_return。最后要說(shuō)明的是,一個(gè)線程不能被多個(gè)線程等待,否那么第一個(gè)接收到信號(hào)的線程成功返回,其余調(diào)用pthread_join的線程那么返回錯(cuò)誤代碼ESRCH。下面我們來(lái)介紹有關(guān)條件變量的容。使用互斥鎖來(lái)可實(shí)現(xiàn)線程間數(shù)據(jù)的共享和

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論