消息隊列就是一個消息的鏈表。可以把消息看作一個記錄,具有特定的格式。
進程可以向其中按照一定的規則添加新消息;另一些進程則可以從消息隊列中讀走消息。
消息隊列的內核持續性要求每個消息隊列都在系統範圍內對應唯一的鍵值,所以,要獲得一個消息隊列的描述符,必須提供該消息隊列的鍵值。
消息隊列的創建和發送消息:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgget(key_t key, int msgflg)
//創建新的消息隊列
int msgsnd(int msqid, struct msgbuf * msgp, int msgsz, int msgflg)
//向消息隊列中發送一條消息
案例:
struct msgbuf
{
long mtype; /* message type, must be > 0 */
char mtext[256]; /* message data */
};
int main()
{
// 創建消息隊列
int msgid = msgget((key_t)1234, 0666|IPC_CREAT);
if (msgid == -1)
{
perror ("msgget");
return -1;
}
struct msgbuf msg;
msg.mtype = 2;
strcpy (msg.mtext, "hello");
int ret = msgsnd(msgid, &msg, 256, IPC_NOWAIT);
if (ret == -1)
{
perror ("nsgsnd");
return -1;
}
return 0;
}
接收消息:
int msgrcv(int msqid, struct msgbuf* msgp, int msgsz, long msgtp, int msgflg)
//從msqid代表的消息隊列中讀取一個msgtyp類型的消息,並把消息存儲在msgp指向的msgbuf結構中。在成功的讀取了一條消息以後,隊列中的這條消息將被刪除。
案例:
struct msgbuf msg;
int ret = msgrcv(msgid, &msg, 256, 2, IPC_NOWAIT);
if (ret == -1)
{
perror ("nsgsnd");
return -1;
}
printf ("%s\n", msg.mtext);
可以將讀取的消息打印出來。
函數msgctl可以控制隊列,包括刪除隊列的功能。
信號通信
信號通信就不講太多了,這裏主要通過幾個案例來介紹一下
signal:
// 信號處理函數
void handle(int signum)
{
printf ("捕捉到一個信號 %d\n", signum);
}
int main()
{
signal(SIGINT, handle);
signal(SIGTERM, handle);
while (1);
return 0;
}
主要用來處理信號,執行了signal()調用後,進程只要接收到類型爲sig的信號,不管其正在執行程序的哪一部分,就立即執行func()函數。當func()函數執行結束後,控制權返回進程被中斷的那一點繼續執行。
kill:
int main()
{
//while (1)
{
kill (18027,9);
sleep(1);
}
return 0;
}
kill命令用來刪除執行中的程序或工作。
alarm:
void handle(int signum)
{
printf ("hello world\n");
// 定時器重置
alarm(2);
}
int main()
{
// 定時器是一次性的
alarm(2);
signal(SIGALRM, handle);
while (1);
return 0;
}
alarm也稱爲鬧鐘函數,它可以在進程中設置一個定時器,當定時器指定的時間到時,它向進程發送SIGALRM信號。
sigaction:
// 信號處理函數
void handle(int signum)
{
printf ("hello world\n");
// 定時器重置
alarm(2);
}
int main()
{
// 定時器是一次性的
alarm(2);
struct sigaction act;
act.sa_handler = handle;
sigaction(SIGALRM, &act, NULL);
while (1);
return 0;
}
sigaction是一個函數,可以用來查詢或設置信號處理方式。