Ⅰ 計算機程序設計基礎的實驗報告怎麼寫
1
實驗要求
:
1.
實驗前按實驗報告格式要求,寫出預實驗報告,注意留出記錄結果的空間。
2.
認真實驗
,
注意記錄
3.
撰寫實驗報告
.
按時上交
.
實驗報告格式:
實驗
*
***** ***** *****
一、
實驗目的
照抄實驗指導的內容。
二、
實驗步驟和內容
包括:
1
.實驗題目要求。
2
.源程序清單
3
.預期結果
3
.上機執行或調試結果:包括原始數據、相應的運行結果和必要的說明
三、
實驗體會
調試中遇到的問題及解決辦法;若最終未完成調試,要試著分析原因;調試程
序的心得與體會;其他演算法的存在與實踐;對課程及實驗的建議等。
Ⅱ 操作系統管理linux 系統進程實驗報告
什麼是進程
比如:windows上安裝的QQ,我們會將其稱為QQ程序,那麼當QQ運行之後,在任務管理器中,我們可以看到QQ程序在運行著,此時,我們稱其為:QQ進程。
言簡意賅總結:當我們運行一個程序,那麼我們將該程序叫進程
注意:
1.當程序運行為進程後,系統會為該進程分配內存,以及運行的身份和許可權。
2.在進程運行的過程中,伺服器上回有各種狀態來表示當前進程的指標信息。
進程是已啟動的可執行程序的運行實例,進程有以下組成部分:
分配內存, 已分配內存的地址空間
安全屬性, 進程的運行身份和許可權
進程代碼, 運行一個或多個的線程
進程狀態, 進程運行後的多種狀態
靜態程序, 二進制文件, 靜態/bin/ls, /usr/sbin/sshd
動態進程, 程序運行的過程, 有生命周期及運行狀態
進程的運行環境,包括以下幾個部分:
局部和全局變數
當前的調度上下文
分配給進程使用的系統資源,例如文件描述符、網路埠等
給進程分配對應的pid,ppid
程序和進程的區別
1.程序是數據和指令的集合,是一個靜態的概念,比如/bin/ls、/bin/cp等二進制文件,同事程序可以長期存在系統中。
2.進程是一個程序的運行過程,是一個動態概念,進程是存在生命周期概念的,也就是說進程會隨著程序的終止而銷毀,不會永遠在系統中存在。
進程的生命周期
程序運行時進程的狀態關系:
1.當父進程接收到任務調度時,會通過fork派生子進程來處理,那麼子進程會集成父進程的衣缽。
2.子進程在處理任務代碼時,父進程會進入等待的狀態...
3.如果子進程在處理任務過程中,父進程退出了,子進程沒有退出,那麼這些子進程就沒有父進程來管理了,就變成了僵屍進程。
4.每個進程都會有自己的PID號,(process id)子進程則PPID
Ⅲ linux中設計一個shell腳本程序可以接受命令行輸入的參數執行相應的菜單命令
echo "------------------------"
echo "1、命令1"
echo "2、命令2"
echo "3、命令3"
echo "------------------------"
echo "請輸入要執行的菜單命令(1/2/3):"
read com
case $com in
1)
命令1
;;
2)
命令2
;;
3)
命令3
;;
*)
echo "輸入命令錯誤"
;;
Ⅳ 實驗報告怎樣寫啊
一, 程序功能
本程序利用指針,鏈表,文件,以及字元串等各種操作,實現程序功能:字典管理。
二, 題目分析
與前兩題不同,本題需大量利用指針和鏈表操作。這無形中增加了題目的難度。由於指針這部分知識掌握得不牢固,加上鏈表和文件都是新學的內容,編程過程遇到了一些困難,調試與查錯一度成為課設的主要工作。
為了更好的完成設計,我復習了指針這部分內容,鞏固了鏈表和文件兩部分知識。
在完成課設過程中,我發現困擾我的地方不是編寫插入,刪除,查找這些函數,而是建立初始鏈表。
我首先編了三個函數:creat,insert_a_word,list,和一個main函數。調試時發現調用list函數輸出除了原來insert的字元串,還有一些亂碼,這就說明以上三個函數的某個或幾個有問題。後來我把目標放在creat函數上。我本來是想模仿書上的creat 函數,但是要從文件上讀取字元串,就要用到fscanf,由於操作的不純熟,空間的分配出現了問題,在初始鏈表的時候帶進了一些亂碼。後來我重新編了creat函數,解決了這個問題。
解決了初始鏈表的問題以後,遇到的問題無非是指針上的操作錯誤,往往一編譯就出現很多警告和錯誤,於是一個一個找,一個一個調。這些花費了我很長時間,以至於一看到藍屏下的出錯信息就想逃。這些錯誤後來都被我解決了。
在完成課設過程中,我是一邊出錯一邊改錯,一邊調試一邊翻書,進展緩慢。不過也是因為出了錯,翻了書,我發現了自己知識體系中的不足之處,鞏固了薄弱的地方。
大體編完了以後,我又對程序進行了完善。比如說增加了全局變數n,在輸出插入單詞成功時輸出插入單詞的個數。經過這個程序設計的編寫,我覺得作為一個編程者,首先,必須有嚴謹的作風:因為一個程序中小小的一點不足在最後的運行時都會對整個程序產生不可忽視的影響,甚至使程序終止,不能運行下去;其次,還必須有足夠的耐心去觀察解決出現的一系列問題;當然,還必須有較強的邏輯思維能力,因為程序出現錯誤不是光有耐心就能解決的,必須利用邏輯思維能力,一步步地排除錯誤
三、源程序
或者;
一. 程序功能
設計一個單向鏈表類,完成一個通訊錄的簡單管理工作。通訊錄是一個簡單的資料庫庫表,每個結點包含一個人的所有通訊信息。
程序的執行過程為:循環顯示主菜單,用戶在Choice處輸入選項,即按照功能列表輸入1-9的任意一個數字,按回車後,執行響應的功能。
各菜單項功能如下:
1、 Add Record (增加記錄)
提示輸入各欄位。一次輸入一個人的數據。
2、 Delete Record (刪除記錄)
輸入待刪除記錄的姓名,顯示該姓名下的所有信息,讓用戶再次確認是否要刪除
3、 Display All Record(顯示所有記錄)
按順序顯示庫中所有記錄,每屏顯示10條記錄。每顯示10條,用戶按<Enter>鍵繼續顯示下一屏。
4、 Query(按姓名查找並顯示一個記錄)
輸入姓名,顯示該姓名下的所有信息
5、 Modify Record(按姓名查找,修改一個記錄)
輸入姓名,顯示該姓名下的所有信息。然後,在子菜單中提示修改哪個數據。
6、 Add from a Text File(從正文文件中添加數據到庫表中)
用戶可事前建立一個正文文件,存放待加入的數據,然後從該文件中一次性導入多個人員的數據。程序運行時,提示輸入正文文件的文件名。
7、 Write to a Text File
將庫表中的數據寫入一個正文文件中。
8、 Sort(排序庫表)
首先顯示當前排序關鍵字,然後 提示是否需要改變,用戶根據需要回答是否需要改變。系統中有兩種排序方式,一種是按姓名排序,一種是按辦公室電話排序。改變排序的方式
的意義是在兩種排序方式之間的切換。
9、 Quit(退出系統)
二. 添加的一些功能
1.程序設計過程中我添加了報錯系統,例如我定義了int isnumber(char a[])和int ischar(char a[])2個函數,分別用於判斷用戶輸入的字元串是否為數字或非數字字元串。
2.我還添加了清屏功能,在適當的地方添加此功能可以方便用戶使用。
3.在void add(Addrlist &addrlist)函數中我還添加了提示「已經添加同名聯系人,是否需要修改新聯系人的各項記錄?(y/n)並確認」的功能。
4.在void del(Addrlist &addrlist)函數中我添加了確認2次輸入的待刪除姓名一致的功能,而且提示用戶確認刪除。
5.在void modify(Addrlist &addrlist)函數中我還添加了可以一次修改多個信息,可以隨時返回的功能,更方便用戶使用。
6.在void addfromtxtfile(Addrlist &addrlist)函數中,導入數據時系統顯示重名信息並自動過濾重名信息。
三.程序設計過程中的一些感想
剛開始接到設計題目的時候感覺很是幸運,因為我知道強化班他們也學過C++,而且也做過課程設計。他們的題目是要做一個圖書館的管理系統,那可是很艱巨的任務呀!大家選擇比較多的應該是我的這個通訊錄了,一看好多函數書上都有,就算是我最頭疼的鏈表書上也有詳細的過程。好象事情從來就是想起來容易做起來難,當我開始要做這個課程設計的時候,我竟然不知道如何下手。也可能是人天生的惰性在起作用,一開始我確實想找強化班的兄弟幫我設計一下,畢竟他們有經驗,可以幫我開個好頭。後來還是決定自己來做,雖然做得可能會稍微差一點。既然學習了就應該自己去實現。
在做的過程中遇到了很多麻煩,雖然我早有心理准備,但還是令我傷透了腦筋。只怪自己平時看書太少,其實有很多東西在書上都可以找到答案的。可是還是有一些問題我實在沒有辦法解決。
我開始只是想自己做一套程序,這會讓我有一種自豪感,沒想到到了最後時期,仍然有些問題沒有解決。只好求助同學。在同學的幫助之下,總算是解決了最後的問題。但由於水平有限,和其他同學比起來,我的程序顯得那麼笨拙。
通過這次的課程設計使我更深刻地體會到事情從來都不像你想像的那麼簡單,只有去做,才會真正感到它的困難。同時也使我明白了,什麼時候都不要忘記最基礎的東西。因為平時沒有注意看書,使我在設計的過程中吃盡了苦頭,浪費了不少時間。
雖然一開始雄心勃勃要自己獨立完成程序,可是最後還是要求助於別人。這與最開始的想法有些違背。有的時候的確不應該自己鑽牛角尖,每個同學都可以成為自己的老師,虛心請教是必不可少的。
三、源程序
Ⅳ linux的課程設計,急!!!!!!!
這么龐大的工作量
找專業的搞一兩天,起碼幾千塊。找學長學姐搞,幾百塊就可以了
Ⅵ 一個Linux多進程編程
1 引言
對於沒有接觸過Unix/Linux操作系統的人來說,fork是最難理解的概念之一:它執行一次卻返回兩個值。fork函數是Unix系統最傑出的成就之一,它是七十年代UNIX早期的開發者經過長期在理論和實踐上的艱苦探索後取得的成果,一方面,它使操作系統在進程管理上付出了最小的代價,另一方面,又為程序員提供了一個簡潔明了的多進程方法。與DOS和早期的Windows不同,Unix/Linux系統是真正實現多任務操作的系統,可以說,不使用多進程編程,就不能算是真正的Linux環境下編程。
多線程程序設計的概念早在六十年代就被提出,但直到八十年代中期,Unix系統中才引入多線程機制,如今,由於自身的許多優點,多線程編程已經得到了廣泛的應用。
下面,我們將介紹在Linux下編寫多進程和多線程程序的一些初步知識。
2 多進程編程
什麼是一個進程?進程這個概念是針對系統而不是針對用戶的,對用戶來說,他面對的概念是程序。當用戶敲入命令執行一個程序的時候,對系統而言,它將啟動一個進程。但和程序不同的是,在這個進程中,系統可能需要再啟動一個或多個進程來完成獨立的多個任務。多進程編程的主要內容包括進程式控制制和進程間通信,在了解這些之前,我們先要簡單知道進程的結構。
2.1 Linux下進程的結構
Linux下一個進程在內存里有三部分的數據,就是"代碼段"、"堆棧段"和"數據段"。其實學過匯編語言的人一定知道,一般的CPU都有上述三種段寄存器,以方便操作系統的運行。這三個部分也是構成一個完整的執行序列的必要的部分。
"代碼段",顧名思義,就是存放了程序代碼的數據,假如機器中有數個進程運行相同的一個程序,那麼它們就可以使用相同的代碼段。"堆棧段"存放的就是子程序的返回地址、子程序的參數以及程序的局部變數。而數據段則存放程序的全局變數,常數以及動態數據分配的數據空間(比如用malloc之類的函數取得的空間)。這其中有許多細節問題,這里限於篇幅就不多介紹了。系統如果同時運行數個相同的程序,它們之間就不能使用同一個堆棧段和數據段。
2.2 Linux下的進程式控制制
在傳統的Unix環境下,有兩個基本的操作用於創建和修改進程:函數fork( )用來創建一個新的進程,該進程幾乎是當前進程的一個完全拷貝;函數族exec( )用來啟動另外的進程以取代當前運行的進程。Linux的進程式控制制和傳統的Unix進程式控制制基本一致,只在一些細節的地方有些區別,例如在Linux系統中調用vfork和fork完全相同,而在有些版本的Unix系統中,vfork調用有不同的功能。由於這些差別幾乎不影響我們大多數的編程,在這里我們不予考慮。
2.2.1 fork( )
fork在英文中是"分叉"的意思。為什麼取這個名字呢?因為一個進程在運行中,如果使用了fork,就產生了另一個進程,於是進程就"分叉"了,所以這個名字取得很形象。下面就看看如何具體使用fork,這段程序演示了使用fork的基本框架:
void main(){
int i;
if ( fork() == 0 ) {
/* 子進程程序 */
for ( i = 1; i <1000; i ++ ) printf("This is child process\n");
}
else {
/* 父進程程序*/
for ( i = 1; i <1000; i ++ ) printf("This is process process\n");
}
}
程序運行後,你就能看到屏幕上交替出現子進程與父進程各列印出的一千條信息了。如果程序還在運行中,你用ps命令就能看到系統中有兩個它在運行了。
那麼調用這個fork函數時發生了什麼呢?fork函數啟動一個新的進程,前面我們說過,這個進程幾乎是當前進程的一個拷貝:子進程和父進程使用相同的代碼段;子進程復制父進程的堆棧段和數據段。這樣,父進程的所有數據都可以留給子進程,但是,子進程一旦開始運行,雖然它繼承了父進程的一切數據,但實際上數據卻已經分開,相互之間不再有影響了,也就是說,它們之間不再共享任何數據了。它們再要交互信息時,只有通過進程間通信來實現,這將是我們下面的內容。既然它們如此相象,系統如何來區分它們呢?這是由函數的返回值來決定的。對於父進程,fork函數返回了子程序的進程號,而對於子程序,fork函數則返回零。在操作系統中,我們用ps函數就可以看到不同的進程號,對父進程而言,它的進程號是由比它更低層的系統調用賦予的,而對於子進程而言,它的進程號即是fork函數對父進程的返回值。在程序設計中,父進程和子進程都要調用函數fork()下面的代碼,而我們就是利用fork()函數對父子進程的不同返回值用if...else...語句來實現讓父子進程完成不同的功能,正如我們上面舉的例子一樣。我們看到,上面例子執行時兩條信息是交互無規則的列印出來的,這是父子進程獨立執行的結果,雖然我們的代碼似乎和串列的代碼沒有什麼區別。
讀者也許會問,如果一個大程序在運行中,它的數據段和堆棧都很大,一次fork就要復制一次,那麼fork的系統開銷不是很大嗎?其實UNIX自有其解決的辦法,大家知道,一般CPU都是以"頁"為單位來分配內存空間的,每一個頁都是實際物理內存的一個映像,象INTEL的CPU,其一頁在通常情況下是4086位元組大小,而無論是數據段還是堆棧段都是由許多"頁"構成的,fork函數復制這兩個段,只是"邏輯"上的,並非"物理"上的,也就是說,實際執行fork時,物理空間上兩個進程的數據段和堆棧段都還是共享著的,當有一個進程寫了某個數據時,這時兩個進程之間的數據才有了區別,系統就將有區別的"頁"從物理上也分開。系統在空間上的開銷就可以達到最小。
下面演示一個足以"搞死"Linux的小程序,其源代碼非常簡單:
void main()
{
for( ; ; ) fork();
}
這個程序什麼也不做,就是死循環地fork,其結果是程序不斷產生進程,而這些進程又不斷產生新的進程,很快,系統的進程就滿了,系統就被這么多不斷產生的進程"撐死了"。當然只要系統管理員預先給每個用戶設置可運行的最大進程數,這個惡意的程序就完成不了企圖了。
2.2.2 exec( )函數族
下面我們來看看一個進程如何來啟動另一個程序的執行。在Linux中要使用exec函數族。系統調用execve()對當前進程進行替換,替換者為一個指定的程序,其參數包括文件名(filename)、參數列表(argv)以及環境變數(envp)。exec函數族當然不止一個,但它們大致相同,在Linux中,它們分別是:execl,execlp,execle,execv,execve和execvp,下面我只以execlp為例,其它函數究竟與execlp有何區別,請通過manexec命令來了解它們的具體情況。
一個進程一旦調用exec類函數,它本身就"死亡"了,系統把代碼段替換成新的程序的代碼,廢棄原有的數據段和堆棧段,並為新程序分配新的數據段與堆棧段,唯一留下的,就是進程號,也就是說,對系統而言,還是同一個進程,不過已經是另一個程序了。(不過exec類函數中有的還允許繼承環境變數之類的信息。)
那麼如果我的程序想啟動另一程序的執行但自己仍想繼續運行的話,怎麼辦呢?那就是結合fork與exec的使用。下面一段代碼顯示如何啟動運行其它程序:
char command[256];
void main()
{
int rtn; /*子進程的返回數值*/
while(1) {
/* 從終端讀取要執行的命令 */
printf( ">" );
fgets( command, 256, stdin );
command[strlen(command)-1] = 0;
if ( fork() == 0 ) {
/* 子進程執行此命令 */
execlp( command, command );
/* 如果exec函數返回,表明沒有正常執行命令,列印錯誤信息*/
perror( command );
exit( errorno );
}
else {
/* 父進程, 等待子進程結束,並列印子進程的返回值 */
wait ( &rtn );
printf( " child process return %d\n",. rtn );
}
}
}
此程序從終端讀入命令並執行之,執行完成後,父進程繼續等待從終端讀入命令。熟悉DOS和WINDOWS系統調用的朋友一定知道DOS/WINDOWS也有exec類函數,其使用方法是類似的,但DOS/WINDOWS還有spawn類函數,因為DOS是單任務的系統,它只能將"父進程"駐留在機器內再執行"子進程",這就是spawn類的函數。WIN32已經是多任務的系統了,但還保留了spawn類函數,WIN32中實現spawn函數的方法同前述UNIX中的方法差不多,開設子進程後父進程等待子進程結束後才繼續運行。UNIX在其一開始就是多任務的系統,所以從核心角度上講不需要spawn類函數。
在這一節里,我們還要講講system()和popen()函數。system()函數先調用fork(),然後再調用exec()來執行用戶的登錄shell,通過它來查找可執行文件的命令並分析參數,最後它么使用wait()函數族之一來等待子進程的結束。函數popen()和函數system()相似,不同的是它調用pipe()函數創建一個管道,通過它來完成程序的標准輸入和標准輸出。這兩個函數是為那些不太勤快的程序員設計的,在效率和安全方面都有相當的缺陷,在可能的情況下,應該盡量避免。
2.3 Linux下的進程間通信
詳細的講述進程間通信在這里絕對是不可能的事情,而且筆者很難有信心說自己對這一部分內容的認識達到了什麼樣的地步,所以在這一節的開頭首先向大家推薦著名作者Richard Stevens的著名作品:《Advanced Programming in the UNIX Environment》,它的中文譯本《UNIX環境高級編程》已有機械工業出版社出版,原文精彩,譯文同樣地道,如果你的確對在Linux下編程有濃厚的興趣,那麼趕緊將這本書擺到你的書桌上或計算機旁邊來。說這么多實在是難抑心中的景仰之情,言歸正傳,在這一節里,我們將介紹進程間通信最最初步和最最簡單的一些知識和概念。
首先,進程間通信至少可以通過傳送打開文件來實現,不同的進程通過一個或多個文件來傳遞信息,事實上,在很多應用系統里,都使用了這種方法。但一般說來,進程間通信(IPC:InterProcess Communication)不包括這種似乎比較低級的通信方法。Unix系統中實現進程間通信的方法很多,而且不幸的是,極少方法能在所有的Unix系統中進行移植(唯一一種是半雙工的管道,這也是最原始的一種通信方式)。而Linux作為一種新興的操作系統,幾乎支持所有的Unix下常用的進程間通信方法:管道、消息隊列、共享內存、信號量、套介面等等。下面我們將逐一介紹。
2.3.1 管道
管道是進程間通信中最古老的方式,它包括無名管道和有名管道兩種,前者用於父進程和子進程間的通信,後者用於運行於同一台機器上的任意兩個進程間的通信。
無名管道由pipe()函數創建:
#include <unistd.h>
int pipe(int filedis[2]);
參數filedis返回兩個文件描述符:filedes[0]為讀而打開,filedes[1]為寫而打開。filedes[1]的輸出是filedes[0]的輸入。下面的例子示範了如何在父進程和子進程間實現通信。
#define INPUT 0
#define OUTPUT 1
void main() {
int file_descriptors[2];
/*定義子進程號 */
pid_t pid;
char buf[256];
int returned_count;
/*創建無名管道*/
pipe(file_descriptors);
/*創建子進程*/
if((pid = fork()) == -1) {
printf("Error in fork\n");
exit(1);
}
/*執行子進程*/
if(pid == 0) {
printf("in the spawned (child) process...\n");
/*子進程向父進程寫數據,關閉管道的讀端*/
close(file_descriptors[INPUT]);
write(file_descriptors[OUTPUT], "test data", strlen("test data"));
exit(0);
} else {
/*執行父進程*/
printf("in the spawning (parent) process...\n");
/*父進程從管道讀取子進程寫的數據,關閉管道的寫端*/
close(file_descriptors[OUTPUT]);
returned_count = read(file_descriptors[INPUT], buf, sizeof(buf));
printf("%d bytes of data received from spawned process: %s\n",
returned_count, buf);
}
}
在Linux系統下,有名管道可由兩種方式創建:命令行方式mknod系統調用和函數mkfifo。下面的兩種途徑都在當前目錄下生成了一個名為myfifo的有名管道:
方式一:mkfifo("myfifo","rw");
方式二:mknod myfifo p
生成了有名管道後,就可以使用一般的文件I/O函數如open、close、read、write等來對它進行操作。下面即是一個簡單的例子,假設我們已經創建了一個名為myfifo的有名管道。
/* 進程一:讀有名管道*/
#include <stdio.h>
#include <unistd.h>
void main() {
FILE * in_file;
int count = 1;
char buf[80];
in_file = fopen("mypipe", "r");
if (in_file == NULL) {
printf("Error in fdopen.\n");
exit(1);
}
while ((count = fread(buf, 1, 80, in_file)) > 0)
printf("received from pipe: %s\n", buf);
fclose(in_file);
}
/* 進程二:寫有名管道*/
#include <stdio.h>
#include <unistd.h>
void main() {
FILE * out_file;
int count = 1;
char buf[80];
out_file = fopen("mypipe", "w");
if (out_file == NULL) {
printf("Error opening pipe.");
exit(1);
}
sprintf(buf,"this is test data for the named pipe example\n");
fwrite(buf, 1, 80, out_file);
fclose(out_file);
}
2.3.2 消息隊列
消息隊列用於運行於同一台機器上的進程間通信,它和管道很相似,事實上,它是一種正逐漸被淘汰的通信方式,我們可以用流管道或者套介面的方式來取代它,所以,我們對此方式也不再解釋,也建議讀者忽略這種方式。
2.3.3 共享內存
共享內存是運行在同一台機器上的進程間通信最快的方式,因為數據不需要在不同的進程間復制。通常由一個進程創建一塊共享內存區,其餘進程對這塊內存區進行讀寫。得到共享內存有兩種方式:映射/dev/mem設備和內存映像文件。前一種方式不給系統帶來額外的開銷,但在現實中並不常用,因為它控制存取的將是實際的物理內存,在Linux系統下,這只有通過限制Linux系統存取的內存才可以做到,這當然不太實際。常用的方式是通過shmXXX函數族來實現利用共享內存進行存儲的。
首先要用的函數是shmget,它獲得一個共享存儲標識符。
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, int size, int flag);
這個函數有點類似大家熟悉的malloc函數,系統按照請求分配size大小的內存用作共享內存。Linux系統內核中每個IPC結構都有的一個非負整數的標識符,這樣對一個消息隊列發送消息時只要引用標識符就可以了。這個標識符是內核由IPC結構的關鍵字得到的,這個關鍵字,就是上面第一個函數的key。數據類型key_t是在頭文件sys/types.h中定義的,它是一個長整形的數據。在我們後面的章節中,還會碰到這個關鍵字。
當共享內存創建後,其餘進程可以調用shmat()將其連接到自身的地址空間中。
void *shmat(int shmid, void *addr, int flag);
shmid為shmget函數返回的共享存儲標識符,addr和flag參數決定了以什麼方式來確定連接的地址,函數的返回值即是該進程數據段所連接的實際地址,進程可以對此進程進行讀寫操作。
使用共享存儲來實現進程間通信的注意點是對數據存取的同步,必須確保當一個進程去讀取數據時,它所想要的數據已經寫好了。通常,信號量被要來實現對共享存儲數據存取的同步,另外,可以通過使用shmctl函數設置共享存儲內存的某些標志位如SHM_LOCK、SHM_UNLOCK等來實現。
Ⅶ linux並發程序設計 實訓小結,急求!!!!字數500~600
實驗6 Linux進程並發程序設計
1 實驗目的:
掌握Linux環境下的進程並發程序及管道應用程序的編寫要點。
2 實驗內容和實驗步驟:
(1) 調試並運行3.10的並發程序設計實例,顯示結果是什麼,並分析之。
通過pipeline.c這個文件,調用child1.c和father1.c這兩個程序,father1.c寫入管理,然後再通過child1.c讀管道,因此輸出為以上結果。
(2) 編寫一個並發程序,父進程列印「The Parent is running」;子進程列印「The Child is running」;
#include<stdio.h>
#include<unistd.h>
main()
{
int p1;
while((p1=fork())==-1);
if(p1>0)
{
wait(0);
printf("The Parent is running.\n");
}
else
{
printf("The Child is running.\n");
exit(0);
}
}
結果為:
The Child is running.
The Parent is running.
(3) 編寫一個管道應用程序,父進程通過管道提供字元串「put the string into the pipe.」給子進程,子進程通過管道接收這條信息,然後列印輸出。
#include<stdio.h>
#include<unistd.h>
main()
{
int p1,fd[2];
char outpipe[50]; //定義讀緩沖區
char inpipe[50]="put the string into the pipe."; //定義寫緩沖區
pipe(fd); //創建無名管道fd
while((p1=fork())==-1);
if (p1>0) //父進程返回
{
write(fd[1],inpipe,50); //寫信息到管道
wait(0);
}
else //子進程返回
{
read(fd[0],outpipe,50); //從管道讀信息到讀緩沖區
printf("%s\n",outpipe); //顯示讀到的信息
exit(0);
}
}
結果為:
put the string into the pipe.
3.實驗要求:寫出實驗報告並將結果上傳到FTP SERVER上自己的作業目錄。
Ⅷ linux設計程序計算文件的統計信息:字元數,非空白字元總數和文件中字母總數,並將結果輸出到屏幕另一個文件
1.寫一個程序來計算一門課的成績(滿分100).這門課程的記錄包含在一個文件中,該文件將學生的名字,又一個空格,最後是學生10次測驗的分數(全部包含在一行中).測驗分數全部是整數,而且每個分數都以空格分隔.程序將從這個文件讀取輸入,並將輸出發送到另一個文件.輸出文件中的數據與輸入文件中的數據幾乎一樣,唯一的區別在於輸出文件中各行末尾多一個double類型的數.這個數是該學生10次測驗的平均分.
2.寫一個程序,用他糾正c++程序中操作符<<和>>用法錯誤,這兩個操作符與cin和cout配合使用.你的程序將把每個錯誤的cin<<替換成為正確的cin>>,cout>>替換成cout<<.一個比較簡單的版本是,假定每個cin及其後面的<<之間肯定有且只有一個空格,每個cout及其後面的>>之間有且只有一個空格.
3.這個程序用於為一個文本文件中的各行編號.請寫一個程序,要求它從一個文件中讀取文本,並將讀取的每一行同時輸出到屏幕和另一個文件,並為其附加一個行號.要在每行的起始處列印行號.行號佔3個字元位置的一個域,並在這個域中右對齊.在行號之後,請添加一個冒號,再添加一個空格,最後附上原來的文本.每次都應該讀取一個字元,而且要忽略每一行原來在開頭位置的任何空格.
4.寫一個程序,用它計算一個文件下的一下各項統計信息:文件中的字元總數`,非空白字元的總數和文件中的字母數.並將統計結果輸出到屏幕和另一個文件.
做出來的人多謝了~! 絕對有好處z~!