一個例子入門Linux處理序間通訊__Linux

來源:互聯網
上載者:User

先上題目吧:

準備一個大於10M的檔案。
編寫兩個獨立的程式file_read.c和file_write.c。
file_read負責開啟檔案,每次從檔案讀入128-1024個位元組(隨機產生),放入到共用記憶體區;共用記憶體區最大為1024位元組。
file_write負責從共用記憶體中接收資料,並寫入到另一個檔案中。
file_read通過訊息通知file_write每次寫入共用記憶體的位元組數。雙方通過訊號量進行同步。
先來聊聊Linux下處理序間通訊的方式


最初的UNIX的進程通訊:包括管道和訊號 System V處理序間通訊(IPC):包括System V訊息佇列、System V訊號量以及System V共用記憶體區。
Posix 處理序間通訊(IPC):包括Posix訊息佇列、Posix訊號量以及Posix共用記憶體區。
基於通訊端的處理序間通訊:就是Socket,應用於網路中不同機器之間的通訊

訊息佇列是訊息的連結資料表。它克服了前兩種通訊方式中資訊量有限的缺點,具有寫入權限的進程可以按照一定的規則向訊息佇列中添加新訊息;對訊息佇列有讀許可權的進程則可以從訊息佇列中讀取訊息。 共用記憶體:可以說這是最有用的處理序間通訊方式。它使得多個進程可以訪問同一塊記憶體空間,不同進程可以及時看到對方進程中對共用記憶體中資料的更新。這種通訊方式需要依靠某種同步機制,如互斥鎖和訊號量等。          
先仔細分析一下這個題目中要使用到的處理序間通訊技術 1.訊息佇列 2.共用記憶體 3.共用記憶體的同步
先上源碼吧,然後一句一句分析:

#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include<errno.h>#include<sys/shm.h>#include<sys/ipc.h>#include<sys/sem.h>#include<fcntl.h>#include<time.h>struct message           //發送的訊息的結構體,一般是自己定義,但是必須以long 開頭,下面訊息的本文標準是char型數組,但實際上也可以自訂{long msg_type;   //訊息的類型short msg_data;  //訊息的本文};union semun              //此結構體在訊號量的刪除的時候會使用{         int val; struct semid_ds *buf; unsigned short int *array;        struct seminfo *__buf; };int semaphore_v(int semid)                  //即P操作{struct sembuf sem_b;                //sembuf已經在sys/sem.h中定義sem_b.sem_num = 0;                  //訊號量編號,使用單個訊號時,常取值為0 sem_b.sem_op = 1;                   //訊號量操作,取值為-1時表示P操作,為1時表示V操作if(semop(semid, &sem_b, 1) == -1)  //訊號量的操作函數,參數1為訊號量標識符,常是semget()函數的傳回值,參數3為運算元組{                                   //&sem_b中操作個數(元素數目),常取值為一,此函數出錯返回-1printf("%s\n",strerror(errno)); return 0;}return 1; }int semaphore_p(int semid)                   //同上{struct sembuf sem_b; sem_b.sem_num = 0;sem_b.sem_op = -1;if(semop(semid, &sem_b, 1) == -1){printf("%s\n",strerror(errno));return 0;}return 1;}void clearBuf(char *combuff)                  //清空共用記憶體,應該不難理解{int i;for(i=0;i<1024;i++)combuff[i]='\0';}int main(int argc,char **argv){int fd;                    //檔案描述符int qid;                   //訊息佇列標識符key_t key;                 //ipc索引值,沒有它就沒有ipcint semid;                 //訊號量描述符int shmid;                 //共用記憶體描述符char *combuff;             //指向共用記憶體的指標int tempNo;               int temp;struct message msg;        //訊息結構體if(argc!=2)                //如果沒有輸入讀檔案路徑,直接退出{printf("please input the path of testData!\n");exit(1);}if((fd=open(argv[1],O_RDONLY))==-1){       //開啟檔案perror("open");exit(1);}printf("fd %d\n",fd);if((key=ftok(".",'a'))==-1){               //用已知存在的路徑產生ipc索引值,如果兩個或者多個進程使用ftok()的參數相同,則產生的索引值相同perror("ftok");                    //索引值相同是處理序間通訊的基礎exit(1);}printf("key %d\n",key);if((qid=msgget(key,IPC_CREAT|0666))==-1){  //取得訊息佇列描述符perror("msgget");exit(1);}printf("qid %d\n",qid);if((shmid=shmget(key,1024,IPC_CREAT|0777))==-1){ //取得共用記憶體描述符perror("shmget");exit(1);}printf("shmid %d\n",shmid);combuff=(char *)shmat(shmid,NULL,0);        //將指標指向作業系統分配的共用記憶體首地址if((int)combuff==-1){perror("shmget");exit(1);}if((semid=semget(key,1,IPC_CREAT|0666))==-1){//擷取訊號量perror("shmget");exit(1);}printf("semid %d\n",semid);srand(time(0));                              //種下種子,以便後面產生隨機數do{tempNo=rand()%897+128;               //產生隨機數    semaphore_p(semid);                  //在對共用記憶體操作之前先上鎖clearBuf(combuff);temp=read(fd,combuff,tempNo);semaphore_v(semid);                  //操作完成之後釋放鎖msg.msg_data=temp;                   //填充訊息結構體msg.msg_type = getpid(); if((msgsnd(qid,&msg,sizeof(short),0))<0){  //發送訊息perror("message posted");exit(1);}while(strlen(combuff)!=0&&temp!=0);   //等待讀取端取走共用記憶體裡面的資料(讀取端讀取資料後會將共用記憶體清空)                                                      //此等待可以防止共用記憶體裡面的資料被覆蓋,導致寫入的檔案資料不完整}while(temp!=0);exit(0);}
 然後上上代碼中所用到的函數的詳細解析 

最後讀者可以自行寫一下寫檔案進程的代碼,可以向我索取

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.