1.進程通訊的幾種不同形式
1)訊息傳遞:管道、FIFO、訊息佇列
2)同步:互斥鎖、條件變數、讀寫鎖、檔案與記錄鎖、號誌
3)共用記憶體區:匿名共用記憶體區、有名共用記憶體區
4)遠端程序呼叫:Solaris門、sun RPC
2.進程間共用資訊的方法
3.IPC對象的持久性
1)隨進程的持久性
一直存在到開啟該對像的最後一個進程關閉該對象;
如:管道和FIFO.
2)隨核心的持久性
一直存在到核心重新自舉或顯式刪除該對象為止;
如:System V訊息佇列、號誌和共用記憶體區;
Posix訊息佇列、號誌和共用記憶體區;
3)隨檔案的持久性
一直存在到顯式刪除該對象為止;
如:Posix訊息佇列、號誌和共用記憶體區,使用對應檔實現時;
4. 無名管道:只能用於fork之間進程的操作。
命令使用:
cut -f1 -d: </etc/group | sort
/etc/group作為cut命令的輸入,使用重新導向技術;
cut命令的輸出,作為sort的輸入,使用管道技術;
相關函數:
標頭檔:#include <unistd.h>
int pipe(int filedes[2]);
功能:建立管道;
參數:filedes[0] OUT 從管道讀資料描述符;
filedes[1] OUT 向管道寫資料描述符;
返回:0,執行成功;
-1,執行失敗;設定errno。
說明:filedes[0]用O_RDONLY方式開啟;
filedes[1]用O_WRONLY方式開啟;
使用結束時,要確保兩個檔案描述符全部關閉。使用close();
使用時,一個進程讀管道資料,另一個進程寫管道資料;
當向管道寫資料時,需要關閉讀檔案描述符。同時,對應的讀管道資料的進程要
關閉寫資料檔案描述符。
標頭檔:#include <stdio.h>
FILE *popen(const char *command, const char *mode);
功能:建立管道,然後fork一個子進程,接著執行一個exec調用,調用/bin/sh -c執行儲存在command
中的命令字串。
參數:command IN 指向命令字串的指標;
mode IN r(or)w;
返回:用於讀寫的檔案流,執行成功;
NULL,執行失敗;設定errno。
說明:mode = r,popen返回的FILE流指標用於讀command的標準輸出;
mode = w,popen返回的FILE流指標用於向command的標準輸入寫資料。
int pclose(FILE *stream);
功能:關閉I/O流。
參數:stream IN 指定的檔案流;
返回:退出狀態,執行成功;
-1,執行失敗。
說明:
/******************************************進程通訊
****************************************************/
/*無名管道:只能用於fork之間進程的操作。
命令使用:
cut -f1 -d: </etc/group | sort
/etc/group作為cut命令的輸入,使用重新導向技術;
cut命令的輸出,作為sort的輸入,使用管道技術;
相關函數:
標頭檔:#include <unistd.h>
int pipe(int filedes[2]);
功能:建立管道;
參數:filedes[0] OUT 從管道讀資料描述符;
filedes[1] OUT 向管道寫資料描述符;
返回:0,執行成功;
-1,執行失敗;設定errno。
說明:filedes[0]用O_RDONLY方式開啟;
filedes[1]用O_WRONLY方式開啟;
使用結束時,要確保兩個檔案描述符全部關閉。使用close();
使用時,一個進程讀管道資料,另一個進程寫管道資料;
當向管道寫資料時,需要關閉讀檔案描述符。同時,對應的讀管道資料的進程要
關閉寫資料檔案描述符。
標頭檔:#include <stdio.h>
FILE *popen(const char *command, const char *mode);
功能:建立管道,然後fork一個子進程,接著執行一個exec調用,調用/bin/sh -c執行儲存在command
中的命令字串。
參數:command IN 指向命令字串的指標;
mode IN r(or)w;
返回:用於讀寫的檔案流,執行成功;
NULL,執行失敗;設定errno。
說明:mode = r,popen返回的FILE流指標用於讀command的標準輸出;
mode = w,popen返回的FILE流指標用於向command的標準輸入寫資料。
int pclose(FILE *stream);
功能:關閉I/O流。
參數:stream IN 指定的檔案流;
返回:退出狀態,執行成功;
-1,執行失敗。
說明:
*/
/*有名管道(FIFO):能用於無關進程之間的操作。
命令使用:
mkfifo [option] name
mkfifo -m 600 fifo1
建立一個名為fifo的管道;
相關函數:
標頭檔:
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
功能:用mode指定的許可權位建立一個名為pathname的FIFO。
參數:pathname IN FIFO名字
mode IN FIFO的許可權
返回:0,執行成功;
-1,執行失敗;
說明:mode中的值會被進程中的umask修改。
修改規則為mode&~umask
可能返回的錯誤值:EACCESS、EECIST、ENAMETOOLONG、ENOENT、ENOSPC、ENOTDIR、EROFS。
開啟、讀寫、刪除、讀取、寫入操作等同與對檔案操作;
使用函數open、close、unlink、read、write。
注意:FIFO兩端都必須在使用之前開啟;
開啟時通過使用O_NONBLOCK可以使讀寫操作立即返回。
相關問題:
如何擷取和設定進程的umask。
答案:通過umask函數。具體參照本檔案中umask函數的說明。
/*********************************IPC*******************************/
在建立一個system v ipc對象的時候,進程的umask不會修改對象的存取權限;
如果沒有設定存取權限,模式為0,所有人都沒有對它的讀寫權。
/*共用記憶體
命令:ipcs -m 列印共用記憶體;
標頭檔:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
函數:
int shmget(key_t key, int size, int flags);
功能:建立一個新的共用記憶體段,或者返回key指定的共用記憶體段的標示。
參數:key IN 共用段關鍵字.
size IN 共用段的大小.
flags IN 建立標誌.
返回:段標識符,執行成功
-1,執行失敗;
說明:key:IPC_PRIVATE,系統隨機指定一個索引值;
也可以有ftok()函數產生;
也可以自己在標頭檔中定義該索引值。
size:建立共用段的大小,受處理器本身頁大小的限制。
INTEL 4KB,ALPHA 8KB。
flag:IPC_CREAT、IPC_EXCL和一組許可權位(模式)按位”或“的結果。
IPC_EXCL:當段已經存在時,返回-1,而不是段標示符;
IPC_CREAT:如果沒有和KEY關聯的段就建立一個新段。
char *shmat(int shmid, char *shmaddr, int flags);
功能:附加共用記憶體段到調用進程地址空間中。
參數:shmid IN 共用段標識符.
shmaddr IN 共用段的進程映像地址,一般設定為0由進程自動分配。
flags IN 讀寫標誌.SHM_RDONLY,該段唯讀,預設可讀寫。
返回:附加段地址,執行成功
-1,執行失敗;
說明:
int shmds(char *shmaddr);
功能:將進程地址空間中的附加記憶體共用段分離出去。
參數:
shmaddr IN shmat的傳回值。
返回:0,執行成功
-1,執行失敗;
說明:
*/
/*訊息佇列
命令:ipcs -q
標頭檔:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
函數:
int msgget(key_t key, int flags);
功能:返回新的或已有隊列的隊列ID。
參數:key IN 訊息佇列關鍵字.
flags IN 建立標誌。
返回:0,執行成功
-1,執行失敗;
說明:key:IPC_PRIVATE,系統隨機指定一個索引值;
也可以自己在標頭檔中定義該索引值。
flag:IPC_CREAT和一組許可權位(模式)按位”或“的結果。
IPC_CREAT:如果沒有和KEY關聯的段就建立一個新段。
int msgsnd(int msqid, const void *ptr, size_t nbytes, int flags);
功能:向隊列中寫入訊息。
參數:msqid IN 訊息佇列id號。
ptr IN 指向msgbuf結構的指標。
nbytes IN 添加訊息的位元組數
flags IN 建立標誌。
返回:0,執行成功
-1,執行失敗;設定錯誤變數為EAGAIN、EACCES、EFAULT、EIDRM、EINTR、EINVAL、ENOMEM。
說明:struct msgbuf{
long mtype;/*任何大於0的值*/
char mtext[1];/*長度為nbytes-末尾的null字元*/
};
訊息不應該以null結尾;
flag:0, 阻塞方式;
IPC_NOWAIT, 非阻塞方式;
int msgrcv(int msqid, void *ptr, size_t nbytes, long type, int flags);
功能:刪除從隊列返回的訊息。
參數:msqid IN 訊息佇列id號。
ptr IN 指向msgbuf結構的指標。
nbytes IN 讀取訊息的位元組數.
type IN 決定返回哪個訊息。
flags IN 建立標誌。
返回:0,執行成功
-1,執行失敗;設定錯誤變數為EAGAIN、EACCES、EFAULT、EIDRM、EINTR、EINVAL、ENOMEM。
說明:type:0,返回隊列中的第一條訊息;
大於0,返回msg_type等於type的第一條訊息;
小於0,返回msg_type為小於等於type絕對值的最小值的第一條訊息;
flag:MSG_NOERROR, 返回的訊息比nbytes位元組多,截斷到nbytes位元組;
否則返回-1,設定errno值為E2BIG,訊息仍舊在隊列中。
IPC_NOWAIT, 沒有指定類型的訊息,立即返回,設定ENOMSG;
否則阻塞。
int msgctl(int msgid, int cmd, struct msgid_ds *buf);
功能:根據cmd不同值進行不同的操作。
參數:msqid IN 訊息佇列id號。
cmd IN 。
buf OUT 擷取隊列的msgid_ds結構。
返回:0,執行成功
-1,執行失敗;設定錯誤變數為EAGAIN、EACCES、EFAULT、EIDRM、EINTR、EINVAL、ENOMEM。
說明:cmd:IPC_RMID,刪除隊列msgid;
IPC_STAT,用隊列的msgid_ds結構填充buf,並可以查看隊列的內容而不會刪除任何訊息。
IPC_SET,可以改變隊列的UID、GID、訪問模式和隊列的最大位元組數。
*/
/*號誌
命令:ipcs -s
標頭檔:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
函數:
int semget(key_t key, int nsems, int flags);
功能:同另外兩種IPC對象。
int semop(int semid, struct sembuf *semops, unsigned nops);
功能:
參數:
返回:
說明:struct sembuf{
short sem_num;
short sem_op;
short sem_flg;
}
sem_num是號誌的編號,其值從0到nsems-1;
sem_op是執行的操作;為正,號誌控制的資源被釋放,而且號誌的值增加;
為負,調用進程表示它將等待直到受控資源被釋放,此時號誌的值減小而資源被調用進程加鎖;
為0, 調用進程阻塞直到號誌變為0;如果號誌已經是0,調用立即返回。
sem_flg調整semop的行為;
int semctl(int semid, int semnum, int cmd, union semun arg);
功能:
參數:
返回:
說明:
*/
本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/apn172/archive/2010/12/20/6087543.aspx