速來學習,必須要學的進程間通信——消息隊列

什麼是消息隊列?

消息隊列提供了一種從一個進程向另一個進程發送一個數據塊的方法。 每個數據塊都被認為含有一個類型,接收進程可以獨立地接收含有不同類型的數據結構。我們可以通過發送消息來避免命名管道的同步和阻塞問題。但是消息隊列與命名管道一樣,每個數據塊都有一個最大長度的限制。

查看系統中ipc的數量:ipcs

-m shared memory segments 查看共享內存情況

-q message queues 查看消息隊列情況

-s semaphores 查看信號量

-a all (default)

1.創建秘鑰函數

頭文件:

#include

#include

函數原型:

key_t ftok(const char *pathname,int proj_id);

參數一:路徑名

參數二:秘鑰ID,是一個8bit的整型

返回值:成功返回一把秘鑰,失敗返回-1

2.創建消息隊列ipc對象

頭文件:

#include

#include

#include

函數原型:

int msgget(key_t key,int msgflg);

參數一:創建消息隊列的一個秘鑰,必須是唯一的

參數二:IPC_CREAT ---》創建ipc對象

O_EXCL ---》檢查ipc對象是否存在,存在則創建失敗

0666 ---》權限,不能忘了

返回值:成功返回一個ipc對象id,失敗返回-1

3.發送信息msgsnd():

函數原型;

int msgsnd(int msqid, -》IPC對象ID

const void *msgp, -》要發送的消息 該指針指向這個結構體

struct msgbuf {

long mtype; -》發送的消息類型,自己定義一個唯一的整形即可

char mtext[1]; -》數據緩存區

};

size_t msgsz, -》有效數據的大小 mtext裡面的有效數據

int msgflg); -》發送標誌

IPC_NOWAIT -》不阻塞

0 -》阻塞 (但是發送一般不阻塞,除非隊列已滿)

4.接收信息msgrcv():

函數原型:

ssize_t msgrcv(int msqid,-》IPC對象ID

void *msgp, -》數據緩存區 他需要這樣的結構體保存數據

struct msgbuf {

long mtype; -》發送的消息類型,自己定義一個唯一的整形即可

char mtext[1]; -》數據緩存區

};

size_t msgsz, -》要接收數據的大小 ,(按實際數據的大小接收)

long msgtyp, -》重點(指定的接收類型,在發送函數中定義好的類型)

0 接收任何信息

int msgflg);-》接收標誌

IPC_NOWAIT -》不阻塞

0 -》阻塞

5.msgctl函數

該函數用來控制消息隊列,它與共享內存的shmctl函數相似,

函數原型:

int msgctl(int msgid,int command,struct msgid_ds *buf);

參數一:msgid是由msgget函數返回的消息隊列標識符。

參數二:command是將要採取的動作,它可以取3個值,

IPC_STAT:把msgid_ds結構中的數據設置為消息隊列的當前關聯值,即用消息隊列的當前關聯值覆蓋msgid_ds的值。

IPC_SET:如果進程有足夠的權限,就把消息列隊的當前關聯值設置為msgid_ds結構中給出的值

IPC_RMID:刪除消息隊列

參數三:buf是指向msgid_ds結構的指針,它指向消息隊列模式和訪問權限的結構。msgid_ds結構至少包括以下成員:

struct msgid_ds

{

uid_t shm_perm.uid;

uid_t shm_perm.gid;

mode_t shm_perm.mode;

};

--------------------------------------------------------------------------------------------------

示例程序:

發送信息部分:

#include

#include

#include

#include

#include

int main()

{

//創建一把秘鑰

key_t key=ftok("/",120);

//創建消息隊列的IPC對象

int msgid=msgget(key,IPC_CREAT|0666);

if(msgid != -1)

{

printf("creat msgget ok\n");

}

//發送數據

struct msgbuf {

long mtype;

char mtext[100];

};

struct msgbuf sendbuf;

sendbuf.mtype =500;//500類型的數據

// sendbuf.mtext = "123456"; 錯誤

strcpy(sendbuf.mtext,"123456");

msgsnd(msgid,&sendbuf,6,0);

//刪除消息隊列

int ret=msgctl(msgid,IPC_RMID,NULL);

if(ret == 0)

{

printf("ret=%d\n",ret);

}

else

{

perror("rmid:");

}

}

接收信息部分:

#include

#include

#include

#include

#include

int main()

{

//創建一把秘鑰

key_t key=ftok("/",120);

//創建消息隊列的IPC對象

int msgid=msgget(key,IPC_CREAT|0666);

if(msgid != -1)

{

printf("creat msgget ok\n");

}

//接收數據

struct msgbuf {

long mtype;

char mtext[100];

};

struct msgbuf recv;

bzero(recv.mtext,100);//別忘了每次接收前要清空緩衝區

msgrcv(msgid,&recv,6,500,0);//接收500類型的數據

printf("recv=%s\n",recv.mtext);

}

更詳細學習資料的在我的頭條文章仔細的看下,只是粗略的概述了一遍,當然更詳細具體的可以自己去找資料,當然也可以加我的群哈368282579,可以交流的,群內也有針對0基礎的新手資料,項目資源也是很豐富的,希望對各位有所幫助哈


分享到:


相關文章: