Linux作業系統分析(10)

來源:互聯網
上載者:User

提要

       Linux中進程間的通訊機制主要有:管道FIFO,訊號量,訊息,共用記憶體區,通訊端。程式員在使用中可以根據不同的需求進行選擇。


管道

      管道是由核心管理的一個緩衝區,相當於我們放入記憶體中的一個紙條。管道的一端串連一個進程的輸出。這個進程會向管道中放入資訊。管道的另一端串連一個進程的輸入,這個進程取出被放入管道的資訊。一個緩衝區不需要很大,它被設計成為環形的資料結構,以便管道可以被迴圈利用。當管道中沒有資訊的話,從管道中讀取的進程會等待,直到另一端的進程放入資訊。當管道被放滿資訊的時候,嘗試放入資訊的進程會等待,直到另一端的進程取出資訊。當兩個進程都終結的時候,管道也自動消失。

      下面是一個簡單的例子.先看兩個linux中常用的命令

grep

功能說明:尋找檔案裡合格字串。

語  法:grep [-abcEFGhHilLnqrsvVwxy][-A<顯示列數>][-B<顯示列數>][-C<顯示列數>][-d<進行動作>][-e<範本樣式>][-f<範本檔案>][--help][範本樣式][檔案或目錄...]

補充說明:grep 指令用於尋找內容包含指定的範本樣式的檔案,如果發現某檔案的內容符合所指定的範本樣式,預設grep指令會把含有範本樣式的那一列顯示出來。若不指定任何檔案名稱,或是所給予的檔案名稱為“-”,則grep指令會從標準輸入裝置讀取資料。


ls

功能說明:列出目標目錄中所有的子目錄和檔案。

語        法:ls [選項] [目錄名]


通過 " | " 可以建立一個管道,把這兩個進程連結在一起。

終端運行


目錄下檔案名稱中帶in的檔案或檔案夾會顯示出來:



在linux的核心中實際上執行的操作如下:

1.調用pipe() 系統調用,假設pipe()返迴文件描述符3(管道的讀通道)和4(管道的寫通道)。

2.兩次調用fork() 系統調用。

3.兩次調用close() 系統調用來釋放檔案描述符3和4.


使用管道

#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <string.h>int pipe_default[2];int main(){pid_t pid;char buffer[32];memset(buffer, 0, 32);if(pipe(pipe_default) < 0){printf("Faild to create pipe.\n");return 0;}//Child processif(0 == (pid =fork())){close(pipe_default[1]);if(read(pipe_default[0], buffer, 32) > 0){printf("Receive data from server, %s!\n", buffer);}close(pipe_default[0]);}else     //Parent process{close(pipe_default[0]);if(-1 != write(pipe_default[1], "Fuck", strlen("Fuck"))){printf("Send data to client,Fuck!\n");}close(pipe_default[1]);waitpid(pid,NULL,0);}return 1;}




主要解釋一下幾個相關的函數。

int pipe(int filedes[2]);
filedes[0]用於讀出資料,讀取時必須關閉寫入端,即close(filedes[1]);
filedes[1]用於寫入資料,寫入時必須關閉讀取端,即close(filedes[0])


void *memset(void *s, char ch, size_t n);
將s中前n個位元組 (typedef unsigned int size_t)用 ch 替換並返回 s 。


pid_t waitpid(pid_t pid,int * status,int options);

暫時停止目前進程的執行,直到有訊號來到或子進程結束。


read和write分別向管道中傳送資料。


訊號量

       訊號量在建立時需要設定一個初始值,表示同時可以有幾個任務可以訪問該訊號量保護的共用資源,初始值為1就變成互斥鎖(Mutex),即同時只能有一個任務可以訪問訊號量保護的共用資源。

  一個任務要想訪問共用資源,首先必須得到訊號量,擷取訊號量的操作將把訊號量的值減1,若當前訊號量的值為負數,表明無法獲得訊號量,該任務必須掛起在該訊號量的等待隊列等待該訊號量可用;若當前訊號量的值為非負數,表示可以獲得訊號量,因而可以立刻訪問被該訊號量保護的共用資源。

  當任務訪問完被訊號量保護的共用資源後,必須釋放訊號量,釋放訊號量通過把訊號量的值加1實現,如果訊號量的值為非正數,表明有任務等待當前訊號量,因此它也喚醒所有等待該訊號量的任務。

        PV原子操作的具體定義如下:(好好理解,很重要的啊)
● P操作:如果有可用的資源(訊號量值>0),則此操作所在的進程佔用一個資源(此時訊號量值減1,進入臨界區代碼);如果沒有可用的資源(訊號量值=0),則此操作所在的進程被阻塞直到系統將資源分派給該進程(進入等待隊列,一直等到資源輪到該進程)。
● V操作:如果在該訊號量的等待隊列中有進程在等待資源,則喚醒一個阻塞進程;如果沒有進程等待它,則釋放一個資源(即訊號量值加1)。

一個實現PV操作的例子。

      

#include <sys/types.h>#include <sys/ipc.h>#include <sys/sem.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#define DELAY_TIME 5union semun{int val;struct semid_ds *buf;unsigned short *array;};int initsem(int sem_id, int init_value);int del_sem(int sem_id);int sem_p(int sem_id);int sem_v(int sem_id);int main(void){pid_t result;int sem_id;sem_id = semget(ftok(".",'a'),1,0666|IPC_CREAT);init_sem(sem_id, 0);result = fork();if(result == -1){perror("fork error!\n");}else if(result == 0){printf("Child process at id:%d, I run first.\n",getpid());sleep(DELAY_TIME);sem_v(sem_id);}else{sem_p(sem_id);printf("Parent process at id:%d\n",getpid());sem_v(sem_id);del_sem(sem_id);}return 0;}int init_sem(int sem_id, int init_value){union semun sem_union;sem_union.val = init_value;if(semctl(sem_id, 0, SETVAL, sem_union) == 1){perror("Init semaphore!");return -1;}return 0;}int del_sem(int sem_id){union semun sem_union;if(semctl(sem_id, 0, IPC_RMID, sem_union) == 1){perror("Delete semaphore!");return -1;}}int sem_p(int sem_id){struct sembuf sem_b;sem_b.sem_num = 0;sem_b.sem_op = -1;sem_b.sem_flg = SEM_UNDO;if(semop(sem_id, &sem_b, 1) == -1){perror("P operation.");return -1;}return 0;}int sem_v(int sem_id){struct sembuf sem_b;sem_b.sem_num = 0;sem_b.sem_op = 1;sem_b.sem_flg = SEM_UNDO;if(semop(sem_id, &sem_b, 1) == -1){perror("P operation.");return -1;}return 0;}



        在程式中,由於使用了訊號量,確保了每次執行子進程運行在父進程之前。



參考

Linux處理序間通訊(六)---訊號量通訊之semget()、semctl()、semop()及其基礎實驗 - http://blog.csdn.net/mybelief321/article/details/9086151

Linux環境處理序間通訊(一) - http://www.ibm.com/developerworks/cn/linux/l-ipc/part1/

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.