當前位置:編程學習大全網 - 編程語言 - 管道編程

管道編程

進程間的通信模式:

1.管道和命名管道:

管道可用於相關進程之間的通信。除了管道的功能之外,著名的管道還允許不相關的進程之間的通信。

2.信號:

信號是壹種在軟件層面上對中斷機制的模擬。這是壹種復雜的通信模式,用於通知流程事件已經發生。進程接收信號的效果與處理器接收中斷請求的效果相同。

3.消息隊列:

消息隊列是消息的鏈表,克服了上述兩種通信方式信號量有限的缺點,具有寫權限的進程可以按照壹定的規則向消息隊列添加新的信息;對消息隊列具有讀取權限的進程可以從消息隊列中讀取信息。

消息緩沖通信技術最早由Hansen提出,其基本思想是:按照“生產者-消費者”的原則,利用內存中的公共消息緩沖區實現進程間的信息交換。

在存儲器中打開幾個消息緩沖器來存儲消息。每當壹個進程向另壹個進程發送消息時,它都會申請壹個消息緩沖區,將準備好的消息發送到緩沖區,然後將消息緩沖區插入到接收進程的消息隊列中,最後通知接收進程。接收進程收到發送裏程的通知後,從本進程的消息隊列中拾取壹個消息緩沖區,取出需要的信息,然後不定期的將消息緩沖區交給系統。

壹個進程可以向幾個進程發送消息,相反,壹個進程可以從不同的進程接收消息。顯然,進程中消息隊列的操作是壹個關鍵領域。當發送進程向接收進程的消息隊列添加消息時,接收進程不能同時從消息隊列接收和發送消息,反之亦然。

消息緩沖通信機制包括以下內容:

(1)消息緩沖區,這是壹種由以下項目組成的數據結構:

1,消息長度

2.消息正文

3.發報機

4.消息隊列指針

(2)消息隊列頭指針m-q壹般存儲在PCB中。

(1)互斥信號量M,初始值為1,用於互斥訪問消息隊列,在PCB中設置。

(2)同步信號量m-syn,初始值為0,用於消息計數,設置在PCB中。

(3)發送消息原語send

(4)接收消息原語接收(a)

4.***共享內存:

可以說這是最有用的進程間通信方式。它使得多個進程可以訪問同壹個內存空間,不同的進程可以及時看到另壹個進程對內存中數據的更新。這種方法需要依賴壹些同步操作,比如互斥和信號量。

這種通信方式需要解決兩個問題:第壹個問題是如何提供* * *訪問內存;二是公共* * *內存互斥,這是程序開發者的責任。

5.信號量:

它主要用作進程之間以及同壹進程的不同線程之間同步和互斥的手段。

6.插座;

這是壹種比較通用的進程間通信機制,可以用於網絡中不同機器之間的進程間通信,應用廣泛。

t;/*在semval中等待增加的進程數*/

ushort semzcnt/*等待semval的進程數= 0 */

}

# include & ltsys/types . h & gt;

# include & ltsys/IPC . h & gt;

# include & ltsys/SEM . h & gt;

int semget(key_t key,int nsems,int flag);

Key就是上面提到的IPC結構的關鍵字。標誌將決定將來是創建新的信號量集還是引用現有的信號量集。Nsems是集合中信號量的數量。如果您正在創建壹個新的集合(通常在服務器中),您必須指定nsems;如果它引用壹個現有的信號量集(通常在客戶機中),則將nsems指定為0。

Semctl函數用於對信號量進行操作。

int semctl(int semid,int semnum,int cmd,union semun arg);

通過cmd參數實現不同的操作。頭文件sem.h中定義了七種不同的操作,可以在實際編程中作為參考。

semop函數自動執行信號量集合上的操作數組。

int semop(int semid,struct sembuf semoparray[],size _ t nops);

Semoparray是壹個指向信號量操作數組的指針。Nops指定數組中的操作數。

接下來,我們來看壹個具體的例子。它創建壹個具有特定IPC結構的關鍵字和壹個信號量,建立這個信號量的索引,修改索引所指向的信號量的值,最後清除信號量。在下面的代碼中,函數ftok生成我們上面提到的唯壹IPC關鍵字。

# include & ltstdio.h & gt

# include & ltsys/types . h & gt;

# include & ltsys/SEM . h & gt;

# include & ltsys/IPC . h & gt;

void main() {

key_t唯壹密鑰;/*定義壹個IPC關鍵字*/

int id

struct sembuf lock _ it

union semun options

int I;

unique_key = ftok(",",' a ');/*生成關鍵字,字符“a”是壹個隨機種子*/

/*創建新的信號量集合*/

id = semget(unique_key,1,IPC _ CREAT | IPC _ EXCL | 0666);

printf("信號量id=%d\n ",id);

options . val = 1;/*設置變量值*/

semctl(id,0,SETVAL,options);/*設置索引0的信號量*/

/*打印信號量的值*/

i = semctl(id,0,GETVAL,0);

printf("索引0處信號量的值為%d\n ",I);

/*重置下面的信號燈*/

lock _ it . SEM _ num = 0;/*設置哪個信號量*/

lock _ it . SEM _ op =-1;/*定義操作*/

lock _ it.sem _ flg = IPC _ NOWAIT/*操作模式*/

if (semop(id,& amplock_it,1) == -1) {

printf("無法鎖定信號量。\ n ");

退出(1);

}

i = semctl(id,0,GETVAL,0);

printf("索引0處信號量的值為%d\n ",I);

/*清除信號量*/

semctl(id,0,IPC_RMID,0);

}

semget()

您可以使用系統調用semget()來創建新的信號量集或訪問現有的信號量集:

系統調用:SEM get();

原型:int semget (key _ tkey,int nsems,int SEM flg);

返回值:如果成功,返回信號量集的IPC標識符。如果失敗,則返回-1: errno = access(無權限)。

EEXIST(信號量集已經存在,無法創建)

EIDRM(信號量集已被刪除)

ENOENT(信號量集不存在,並且不使用IPC_CREAT)

ENOMEM(內存不足,無法創建新的信號量集)

ENOSPC(超限)

系統調用semget()的第壹個參數是關鍵字值(通常由系統調用ftok()返回)。系統內核將這個值與系統中存在的其他信號量集的關鍵字值進行比較。打開和訪問操作與參數semflg中的內容相關。IPC_CREAT創建壹個信號量集,如果它不存在於系統內核中的話。IPC_EXCL與IPC_CREAT壹起使用時,如果信號量集已經存在,調用將失敗。如果單獨使用IPC_CREAT,semget()要麽返回新創建的信號量集的標識符,要麽返回系統中已經存在的具有相同關鍵字值的信號量的標識符。如果IPC_EXCL和IPC_CREAT壹起使用,則返回新創建的信號量集的標識符或-1。單獨IPC_EXCL是沒有意義的。參數nsems表示應該在新的信號量集中創建的信號量的數量。信號量集中信號量的最大數量在linux/sem.h中定義:

# definesemmsl 32/* & lt;= 512 maxnumofsemaphoresperid */

下面是壹個打開和創建信號量集的程序:

into pen _ semaphore _ set(key _ t keyval,int numsems)

{

intsid

如果(!numsems)

return(-1);

if((sid=semget(mykey,numsems,IPC_CREAT|0660))==-1)

{

return(-1);

}

返回(sid);

}

};

==============================================================

semop()

系統調用:semop();

調用原型:int semop (int semid,struct sembuf * SOPs,unsigned edn SOPs);

返回值:0,如果成功。-1,如果失敗:errno=E2BIG(nsops大於最大ops數)。

EACCESS(權限不足)

EAGAIN(使用了IPC_NOWAIT,但操作無法繼續)

默認(SOPS指向的地址無效)

EIDRM(信號量集已被刪除)

EINTR(睡眠時接收的其他信號)

EINVAL(信號量集不存在或semid無效)

ENOMEM(使用SEM_UNDO,但是沒有足夠的內存來創建所需的數據結構)

ERANGE(信號幅度超出範圍)

第壹個參數是關鍵字值。第二個參數是指向要操作的數組的指針。第三個參數是數組中的操作數。參數sops指向壹個由sembuf組成的數組。這個數組是在linux/sem.h中定義的:

/*semop systemcall接受這些數組*/

structsembuf{

ushortsem _ num/*數組中的信號量索引*/

shortsem _ op/*信號量操作*/

shortsem _ flg/*操作標誌*/

sem_num要處理的信號量數量。

由SEM _ op執行的操作

Sem_flg操作標誌。

如果sem_op為負,信號量將減去它的值。這和信號量控制的資源有關。如果不使用IPC_NOWAIT,調用進程將進入睡眠狀態,直到可以使用信號量控制的資源。如果sem_op是壹個正數,信號量就增加它的值。也就是說,進程釋放由信號量控制的資源。最後,如果sem_op為0,調用進程將調用sleep(),直到信號量的值為0。這在進程等待完全空閑的資源時使用。

===============================================================

semctl()

系統調用:SEM CTL();

原型:int semctl (int semid,int semnum,int cmd,union semunarg);

返回值:如果成功,則為正數。

如果失敗,則為-1: errno = access(權限不足)。

默認(arg指向的地址無效)

EIDRM(信號量集已被刪除)

EINVAL(信號量集不存在或semid無效)

EPERM(EUID無權使用cmd)

ERANGE(信號幅度超出範圍)

系統調用semctl對信號量集執行控制操作。這非常類似於消息隊列中的系統調用msgctl。但是這兩個系統調用的參數略有不同。因為信號量壹般是作為壹組信號量使用,而不是單個信號量。所以在信號量集的操作中,不僅要知道IPC關鍵字值,還要知道信號量集中的具體信號量。兩個系統調用都使用參數cmd,該參數用於指示要操作的特定命令。兩個系統調用中的最後壹個參數也不同。在系統調用msgctl中,最後壹個參數是指向內核中使用的數據結構的指針。我們使用這個數據結構來獲取壹些關於消息隊列的信息,並設置或更改隊列的訪問權限和用戶。然而,信號量支持額外的可選命令,這需要更復雜的數據結構。

系統調用semctl()的第壹個參數是關鍵字值。第二個參數是信號量的數量。

可以在參數cmd中使用的命令如下:

IPC_STAT讀取信號量集的數據結構semid_ds,並將其存儲在semun中的buf參數中。

IPC_SET設置信號量集的數據結構semid_ds中的ipc_perm,其值取自semun中的buf。

  • 上一篇:良好的軟件設計應遵循哪些原則
  • 下一篇:職高學工業機器人怎麽樣
  • copyright 2024編程學習大全網