消息队列就是一个消息的链表。可以把消息看作一个记录,具有特定的格式。
进程可以向其中按照一定的规则添加新消息;另一些进程则可以从消息队列中读走消息。
消息队列的内核持续性要求每个消息队列都在系统范围内对应唯一的键值,所以,要获得一个消息队列的描述符,必须提供该消息队列的键值。
消息队列的创建和发送消息:
#include
#include
#include
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是一个函数,可以用来查询或设置信号处理方式。