1. 程式人生 > >LINUX系統編程之IPC

LINUX系統編程之IPC

LINUX系統編程

LINUX系統編程之IPC(Inter Processes Communication)

一、信號

1.信號的產生

軟件中斷,異步通信,ctrl+c,kill函數,kill命令,硬件異常(段錯誤),軟件異常


2.進程收到信號後可以用如下方法處理:

執行系統默認動作(終止),忽略此信號,執行自定義信號處理函數。


3.信號操作函數

kill(), alarm(), raise(), abort(), pause()

typedef void (*sighandler_t)(int);signal()

sigemptyset(), sigfillset(), sigismember(), sigdelset(), sigaddset()....

信號阻塞集:阻塞信號的接收sigprocmask();


二、管道/命名管道

1.無名管道:類似於一個文件,有2個文件描述符,只存在於內存

半雙工,數據從寫端入,讀端出,先入先出,fd[0]輸出,fd[1]寫入

數據無格式要求,只固定大小,沒有名字,用fork和vfork會繼承其描述符

只有公共祖先進程使用,如父進程創建的管道只有該父進程和其子進程能訪問

int fd[2];

pipe(fd);

write();read();

close(fd);

read從管道中讀取數據時會阻塞,有數據就讀到返回,沒數據則等待,

write從管道寫數據,寫滿阻塞,直到數據被讀出

如果讀進程退出了,寫進程寫數據時也會退出可用fcntl()設置阻塞特性

dup(old)復制old文件描述符並分配一個新的描述符,讀寫位置也會復制

dup2(old, new)復制文件描述符old,分配新的文件描述符new, new也標識old所標識的文件

常用如重定向0,1,2描述符

int fd_stdout=dup(1);復制stdout描述符1

dup2(fd_stdout, 1);將描述符1重新分配給stdout


2.命名管道FIFO

有名字,存在於文件系統,內容只存在於內存

不相關的進程也能使用

命名管道復制後會變成普通文件

mkfifo("./cmd_fifo", 0777);

open("./cmd_fifo", O_RDWR);

write();read();

close();


3.消息隊列

由內核維護的鏈表,消息有格式(結構體),消息有類型,可按照類型隨機查詢

有標識符,只有內核重啟或人工刪除才能刪除

結構體第一個成員代表消息類型必須是long型變量,其它自行定義

發送消息msgsent(msqid, &msg, sizeof(msg)-4, 0);

接收消息msgrcv(msqid, &msg, sizeof(msg)-4, type, 0);返回長度

控制msgctl(msgqid, IPC_RMID, NULL)

typedef struct _msg

{

long mtype;

char mtext[50];

}MSG;

MSG msg;

key=ftok(".", 2012)

msgqid = msgget(key, IPC_CREAT|0666);

if(msgqid==-1)

perror("msgget");

msgrcv(msgqid, &msg, sizeof(msg.mtext), 10, 0);

msgctl(msgqid, IPC_RMID, NULL);


查看消息隊列ipcs -q

刪除消息隊列ipcrm -q msgqid


4.共享內存

多個進程共享給定的存儲空間

最快的通信方式,訪問互斥

查看ipcs -m

刪除ipcrm -m shmid

創建或打開int shmid = shmget(key, size, flag);

內存映射shmat()

解除映射shmdt()

控制shmctl()


LINUX系統編程之IPC