吉林大學(xué)研究所課程-并行計(jì)算課件-第7章 并行程序設(shè)計(jì)_第1頁(yè)
吉林大學(xué)研究所課程-并行計(jì)算課件-第7章 并行程序設(shè)計(jì)_第2頁(yè)
吉林大學(xué)研究所課程-并行計(jì)算課件-第7章 并行程序設(shè)計(jì)_第3頁(yè)
吉林大學(xué)研究所課程-并行計(jì)算課件-第7章 并行程序設(shè)計(jì)_第4頁(yè)
吉林大學(xué)研究所課程-并行計(jì)算課件-第7章 并行程序設(shè)計(jì)_第5頁(yè)
已閱讀5頁(yè),還剩20頁(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)介

并行程序設(shè)計(jì)

—進(jìn)程的創(chuàng)建與終止1 /*2 *exec.c(*)3 *4 *5 */6 7 #include<stdio.h>8 #include<process.h>9 10 void11 main(void)12 {13 char*argv[]={"execed",NULL};14 15 execv("execed",argv);16 17 printf("neverreached.");18 }并行程序設(shè)計(jì)—進(jìn)程的創(chuàng)建與終止/**exec_cp.c*/#include<windows.h>(*)voidmain(void){ STARTUPINFO si; PROCESS_INFORMATION pi;

GetStartupInfo(&si);

CreateProcess(“execed.exe”,NULL,NULL NULL,FALSE,0,NULL,NULL,&si,&pi);}并行程序設(shè)計(jì)—進(jìn)程的創(chuàng)建與終止CreateProcess

說(shuō)明:

WIN32API函數(shù)CreateProcess用來(lái)創(chuàng)建一個(gè)新的進(jìn)程和它的主線程,這個(gè)新進(jìn)程運(yùn)行指定的可執(zhí)行文件。

函數(shù)原型:

BOOLCreateProcess

(

LPCTSTRlpApplicationName,

LPTSTRlpCommandLine,

LPSECURITY_ATTRIBUTESlpProcessAttributes。

LPSECURITY_ATTRIBUTESlpThreadAttributes,

BOOLbInheritHandles,

DWORDdwCreationFlags,

LPVOIDlpEnvironment,

LPCTSTRlpCurrentDirectory,

LPSTARTUPINFOlpStartupInfo,

LPPROCESS_INFORMATIONlpProcessInformation

);

并行程序設(shè)計(jì)—進(jìn)程的創(chuàng)建與終止

參數(shù)

lpApplicationName:指向一個(gè)NULL結(jié)尾的、用來(lái)指定可執(zhí)行模塊的字符串這個(gè)字符串可以使可執(zhí)行模塊的絕對(duì)路徑,也可以是相對(duì)路徑,在后一種情況下,函數(shù)使用當(dāng)前驅(qū)動(dòng)器和目錄建立可執(zhí)行模塊的路徑。這個(gè)參數(shù)可以被設(shè)為NULL,在這種情況下,可執(zhí)行模塊的名字必須處于lpCommandLine參數(shù)的最前面并由空格符與后面的字符分開。這個(gè)被指定的模塊可以是一個(gè)Win32應(yīng)用程序。如果適當(dāng)?shù)淖酉到y(tǒng)在當(dāng)前計(jì)算機(jī)上可用的話,它也可以是其他類型的模塊(如MS-DOS或OS/2)。

在WindowsNT中,如果可執(zhí)行模塊是一個(gè)16位的應(yīng)用程序,那么這個(gè)參數(shù)應(yīng)該被設(shè)置為NULL并且因該在lpCommandLine參數(shù)中指定可執(zhí)行模塊的名稱。16位的應(yīng)用程序是以DOS虛擬機(jī)或Win32上的Windows(WOW)為進(jìn)程的方式運(yùn)行。

lpCommandLine:指向一個(gè)NULL結(jié)尾的、用來(lái)指定要運(yùn)行的命令行。這個(gè)參數(shù)可以為空,那么函數(shù)將使用參數(shù)指定的字符串當(dāng)作要運(yùn)行的程序的命令行。如果lpApplicationName和lpCommandLine參數(shù)都不為空,那么lpApplicationName參數(shù)指定將要被運(yùn)行的模塊,lpCommandLine參數(shù)指定將被運(yùn)行的模塊的命令行。新運(yùn)行的進(jìn)程可以使用GetCommandLine函數(shù)獲得整個(gè)命令行。C語(yǔ)言程序可以使用argc和argv參數(shù)。如果lpApplicationName參數(shù)為空,那么這個(gè)字符串中的第一個(gè)被空格分隔的要素指定可執(zhí)行模塊名。如果文件名不包含擴(kuò)展名,那么.exe將被假定為默認(rèn)的擴(kuò)展名。如果文件名以一個(gè)點(diǎn)(.)結(jié)尾且沒(méi)有擴(kuò)展名,或文件名中包含路徑,.exe將不會(huì)被加到后面。如果文件名中不包含路徑,Windows將按照如下順序?qū)ふ疫@個(gè)可執(zhí)行文件:

1.當(dāng)前應(yīng)用程序的目錄。2.父進(jìn)程的目錄。3.Windows95:Windows系統(tǒng)目錄,可以使用GetSystemDirectory函數(shù)獲得。

WindowsNT:32位Windows系統(tǒng)目錄。可以使用GetSystemDirectory函數(shù)獲得,目錄名是SYSTEM32。4.在WindowsNT中:16位Windows系統(tǒng)目錄。不可以使用Win32函數(shù)獲得這個(gè)目錄,但是它會(huì)被搜索,目錄名是SYSTEM。5.Windows目錄??梢允褂肎etWindowsDirectory函數(shù)獲得這個(gè)目錄。6.列在PATH環(huán)境變量中的目錄。如果被創(chuàng)建的進(jìn)程是一個(gè)以MS-DOS或16位Windows為基礎(chǔ)的應(yīng)用程序,lpCommandLine參數(shù)應(yīng)該是一個(gè)以可執(zhí)行文件的文件名作為第一個(gè)要素的絕對(duì)路徑,因?yàn)檫@樣做可以使32位Windows程序工作的很好,這樣設(shè)置lpCommandLine參數(shù)是最強(qiáng)壯的。并行程序設(shè)計(jì)

—進(jìn)程的創(chuàng)建與終止lpProcessAttributes:指向一個(gè)SECURITY_ATTRIBUTES結(jié)構(gòu)體,這個(gè)結(jié)構(gòu)體決定是否返回的句柄可以被子進(jìn)程繼承。如果lpProcessAttributes參數(shù)為空(NULL),那么句柄不能被繼承。

在WindowsNT中:SECURITY_ATTRIBUTES結(jié)構(gòu)的lpSecurityDescriptor成員指定了新進(jìn)程的安全描述符,如果參數(shù)為空,新進(jìn)程使用默認(rèn)的安全描述符。

在Windows95中:SECURITY_ATTRIBUTES結(jié)構(gòu)的lpSecurityDescriptor成員被忽略。lpThreadAttributes:指向一個(gè)SECURITY_ATTRIBUTES結(jié)構(gòu)體,這個(gè)結(jié)構(gòu)體決定是否返回的句柄可以被子進(jìn)程繼承。如果lpThreadAttributes參數(shù)為空(NULL),那么句柄不能被繼承。

在WindowsNT中,SECURITY_ATTRIBUTES結(jié)構(gòu)的lpSecurityDescriptor成員指定了主線程的安全描述符,如果參數(shù)為空,主線程使用默認(rèn)的安全描述符。

在Windows95中:SECURITY_ATTRIBUTES結(jié)構(gòu)的lpSecurityDescriptor成員被忽略。bInheritHandles:指示新進(jìn)程是否從調(diào)用進(jìn)程處繼承了句柄。如果參數(shù)的值為真,調(diào)用進(jìn)程中的每一個(gè)可繼承的打開句柄都將被子進(jìn)程繼承。被繼承的句柄與原進(jìn)程擁有完全相同的值和訪問(wèn)權(quán)限。dwCreationFlags:指定附加的、用來(lái)控制優(yōu)先類和進(jìn)程的創(chuàng)建的標(biāo)志。并行程序設(shè)計(jì)

—進(jìn)程的創(chuàng)建與終止lpEnvironment:指向一個(gè)新進(jìn)程的環(huán)境塊。如果此參數(shù)為空,新進(jìn)程使用調(diào)用進(jìn)程的環(huán)境。一個(gè)環(huán)境塊存在于一個(gè)由以NULL結(jié)尾的字符串組成的塊中,這個(gè)塊也是以NULL結(jié)尾的。每個(gè)字符串都是name=value的形式。因?yàn)橄嗟葮?biāo)志被當(dāng)作分隔符,所以它不能被環(huán)境變量當(dāng)作變量名。與其使用應(yīng)用程序提供的環(huán)境塊,不如直接把這個(gè)參數(shù)設(shè)為空,系統(tǒng)驅(qū)動(dòng)器上的當(dāng)前目錄信息不會(huì)被自動(dòng)傳遞給新創(chuàng)建的進(jìn)程。對(duì)于這個(gè)情況的探討和如何處理,請(qǐng)參見(jiàn)注釋一節(jié)。環(huán)境塊可以包含Unicode或ANSI字符。如果lpEnvironment指向的環(huán)境塊包含Unicode字符,那么dwCreationFlags字段的CREATE_UNICODE_ENVIRONMENT標(biāo)志將被設(shè)置。如果塊包含ANSI字符,該標(biāo)志將被清空。請(qǐng)注意一個(gè)ANSI環(huán)境塊是由兩個(gè)零字節(jié)結(jié)束的:一個(gè)是字符串的結(jié)尾,另一個(gè)用來(lái)結(jié)束這個(gè)快。一個(gè)Unicode環(huán)境塊石油四個(gè)零字節(jié)結(jié)束的:兩個(gè)代表字符串結(jié)束,另兩個(gè)用來(lái)結(jié)束塊。

lpCurrentDirectory:指向一個(gè)以NULL結(jié)尾的字符串,這個(gè)字符串用來(lái)指定子進(jìn)程的工作路徑。這個(gè)字符串必須是一個(gè)包含驅(qū)動(dòng)器名的絕對(duì)路徑。如果這個(gè)參數(shù)為空,新進(jìn)程將使用與調(diào)用進(jìn)程相同的驅(qū)動(dòng)器和目錄。這個(gè)選項(xiàng)是一個(gè)需要啟動(dòng)啟動(dòng)應(yīng)用程序并指定它們的驅(qū)動(dòng)器和工作目錄的外殼程序的主要條件。

lpStartupInfo:指向一個(gè)用于決定新進(jìn)程的主窗體如何顯示的STARTUPINFO結(jié)構(gòu)體。

lpProcessInformation:指向一個(gè)用來(lái)接收新進(jìn)程的識(shí)別信息的PROCESS_INFORMATION結(jié)構(gòu)體。

返回值:如果函數(shù)執(zhí)行成功,返回非零值。如果函數(shù)執(zhí)行失敗,返回零,可以使用GetLastError函數(shù)獲得錯(cuò)誤的附加信息。

并行程序設(shè)計(jì)

—多線程1 /*2 *thread1.c(*)5 */ 7 #include<stdio.h>8 #include<stdlib.h>9 #include<pthread.h>11 void*thread_entry_point(void*arg)12 {13 printf("thread2!\n");14 } 16 int17 main(void)18 {19 pthread_t pt;20 int ret=0; 22 ret=pthread_create(&pt,NULL,thread_entry_point,NULL);23 if(ret!=0x00)24 {25 printf("pthread_create()failed.\n");26 return(1);27 }29 sleep(1);31 printf("thread1!\n");33 return(0);34 }并行程序設(shè)計(jì)

—多線程1 /*2 *thread2.c(*)5 */7 #include<windows.h>8 #include<stdio.h> 10 DWORDWINAPIthread_entry_point(LPVOIDarg)11 {12 printf("thread2!\r\n");14 return(0);15 }17 int18 main(void)19 {20 HANDLEh=NULL;22 h=CreateThread(NULL,0,thread_entry_point,NULL,0,NULL);23 if(h==NULL)24 {25 printf("CreateThread()failed.\r\n");26 return(1);27 }29 Sleep(1000);31 printf("thread1!\r\n");33 return(0);34 }并行程序設(shè)計(jì)

—多線程1 /*2 *thread3.c5 */ 7 #include<stdio.h>8 #include<pthread.h> 10 //globalvars..11 pthread_mutex_tlock;12 intg_val=0;13 14 void*thread_entry_point(void*arg)15 {16 while(1)17 {18 pthread_mutex_lock(&lock);20 ++g_val;21 printf("thread2,g_val:%d\n",g_val);23 pthread_mutex_unlock(&lock);25 usleep(1000000);26 }27 }28 并行程序設(shè)計(jì)

—多線程29 int30 main(void)31 {32 pthread_tpt;33 intret=0;35 ret=pthread_mutex_init(&lock,NULL);36 if(ret!=0x00)37 {38 printf("pthread_mutex_init()failed.\n");39 return(1);40 }42 ret=pthread_create(&pt,NULL,thread_entry_point,NULL);43 if(ret!=0x00)44 {45 printf("pthread_create()failed.\n");46 return(1);47 }49 while(1)50 {51 pthread_mutex_lock(&lock); 53 ++g_val;54 printf("thread1,g_val:%d\n",g_val);56 pthread_mutex_unlock(&lock); 58 usleep(1000000);59 } 61 pthread_mutex_destroy(&lock);62 }并行程序設(shè)計(jì)

—多線程1 /*2 *thread4.c5 */7 #include<windows.h>8 #include<stdio.h> 10 //globalvars..11 CRITICAL_SECTIONlock;12 intg_val=0; 14 DWORDWINAPIthread_entry_point(LPVOIDarg)15 {16 while(1)17 {18 EnterCriticalSection(&lock);20 ++g_val;21 printf("thread2,g_val:%d\n",g_val);23 LeaveCriticalSection(&lock);25 Sleep(1000);26 }27 }并行程序設(shè)計(jì)

—多線程29 int30 main(void)31 {32 HANDLEh=NULL;33 intret=0;35 InitializeCriticalSection(&lock);37 h=CreateThread(NULL,0,thread_entry_point,NULL,0,NULL);38 if(h==NULL)39 {40 printf("CreateThread()failed.\r\n");41 return(1);42 }44 while(1)45 {46 EnterCriticalSection(&lock);48 ++g_val;49 printf("thread1,g_val:%d\n",g_val);51 LeaveCriticalSection(&lock);53 Sleep(1000);54 }56 DeleteCriticalSection(&lock);58 return(0);59 }并行程序設(shè)計(jì)

—實(shí)例1假定要計(jì)算兩個(gè)N元素向量的點(diǎn)積。代碼給出了這個(gè)任務(wù)的串行程序。integerarraya[1..N],b[1..N]integerdot_product……reada[1..N]fromvector_areadb[1..N]fromvector_bdo_product:=0do_dot(a,b)printdot_product……do_dot(integerarrayx[1..N],integerarrayy[1..N]) fork:=1toN dot_product:=dot_product+x[k]*y[k] endend并行程序設(shè)計(jì)

—實(shí)例1在共享存儲(chǔ)器機(jī)器的兩個(gè)處理器上計(jì)算點(diǎn)積的并行程序首次嘗試sharedintegerarraya[1..N],b[1..N]sharedintegerdot_productsharedlockdot_product_locksharedbarrierdone……reada[1..N]fromvector_areadb[1..N]fromvector_bdo_product:=0do_dot(a,b)printdot_product……do_dot(integerarrayx[1..N],integerarrayy[1..N]) privateintegerid id:=mypid()fork:=(id*N/2)+1to(id+1)*N/2 lock(dot_product_lock) dot_product:=dot_product+x[k]*y[k] unlock(dot_product_lock) endend并行程序設(shè)計(jì)

—實(shí)例1在共享存儲(chǔ)器機(jī)器的兩個(gè)處理器上計(jì)算點(diǎn)積的高效程序sharedintegerarraya[1..N],b[1..N]sharedintegerdot_productsharedlockdot_product_locksharedbarrierdone……reada[1..N]fromvector_areadb[1..N]fromvector_bdo_product:=0create_thread(do_dot,a,b)do_dot(a,b)printdot_product……并行程序設(shè)計(jì)

—實(shí)例在共享存儲(chǔ)器機(jī)器的兩個(gè)處理器上計(jì)算點(diǎn)積的高效程序do_dot(integerarrayx[1..N],integerarrayy[1..N]) privateintegerlocal_dot_productprivateintegerid id:=mypid() local_dot_product?0fork:=(id*N/2)+1to(id+1)*N/2 lock(dot_product_lock) local_dot_product:=local_dot_product+x[k]*y[k] end lock(dot_product_lock) dot_product:=dot_product+local_dot_product unlock(dot_product_lock) barrier(done)end并行程序設(shè)計(jì)

—實(shí)例1在兩個(gè)處理器上計(jì)算點(diǎn)積的消息傳遞程序integerarraya[1..N/2],b[1..N/2],temparray[1..N/2]integerdot_productintegeridintegertemp……id:=mypid()if(id=0)thenreada[1..N/2]fromvector_areadtemparray[1..N/2]fromvector_asend(temparray[1..N/2],1)readb[1..N/2]fromvector_breadtemparray[1..N/2]fromvector_bsend(temparray[1..N/2],1)else receive(a[1..N/2],0) receive(b[1..N/2],0)enddo_product:=0do_dot(a,b)if(id=1) send(dot_product,0) else receive(temp,1) do_product:=do_product+temp printdo_productend……do_dot(integerarrayx[1..N/2],integerarrayy[1..N/2]) fork:=1toN/2 dot_product:=dot_product+x[k]*y[k] endend并行程序設(shè)計(jì)

—實(shí)例2利用Taylor級(jí)數(shù)計(jì)算

,采用Windows多線程方式編程。e可以表示為

可以表示為

并行程序設(shè)計(jì)

—實(shí)例2并行程序設(shè)計(jì)

—實(shí)例2#include<stdio.h>#include<windows.h>#definenum_steps2000000//計(jì)算eDWORDWINAPIThreadCalc_E(PVOIDpParam)//附加線程函數(shù)(計(jì)算e子函數(shù)){double factorial=1;int i=1;double e=1;for(;i<num_steps;i++){factorial*=i;e+=1.0/factorial;}*((double*)pParam)=e;printf(“edoneE=%2.5f\n”,e);return0;}//計(jì)算pi并行程序設(shè)計(jì)

—實(shí)例2DWORDWINAPIThreadCalc_PI(PVOIDpParam)//附加線程函數(shù)(計(jì)算pi子函數(shù)){int i=0;double pi=0;for(;i<num_steps*10;i++){pi+=1.0/(i*4.0+1.0);pi-=1.0/(i*4.0+3.0);}pi=pi*4.0;*((double*)pParam)=pi;printf(“pidonePI=%2.5f\n”,pi);return0;}并行程序設(shè)計(jì)

—實(shí)例2intmain(intargc,char*argv[])//進(jìn)程的主線程入口點(diǎn){HANDLEhHandle_Calc[2];//附加線程的創(chuàng)建doubleresult_e,result_pi;hHandle_Calc[0]=CreateThread(NULL,0,ThreadCalc_E,(void*(&result_e),0,NULL);hHandle_Calc[1]=CreateThread(NULL,0,ThreadCalc_PI,(void*(&resu

溫馨提示

  • 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)論