msgget(),msgrev(),msgctl()
时间: 2023-04-30 14:03:49 浏览: 85
这三个函数都是用于 Linux 系统下的进程间通信。
- msgget() 函数用于创建或获取一个消息队列。如果已经存在该消息队列,则返回其标识符,否则创建一个新的消息队列并返回其标识符。
- msgsnd() 函数用于向消息队列中发送一条消息。需要指定消息队列的标识符、消息指针、消息长度和消息类型等信息。
- msgrcv() 函数用于从消息队列中接收一条消息。需要指定消息队列的标识符、消息指针、消息长度和消息类型等信息。
- msgctl() 函数用于控制消息队列的属性,比如删除消息队列、获取消息队列属性信息等。需要指定消息队列的标识符和控制命令等信息。
这些函数可以在程序中使用,实现不同进程之间的数据传输与同步等功能。
相关问题
使用linux系统提供的系统调用msgget(),msgrev(),msgctl()编制一个长度为1K的消息发送和接受的程序。
以下是一个使用Linux系统调用msgget(), msgrecv(), msgctl()编写的长度为1K的消息发送和接收程序。
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h>
#define MSG_SIZE 1024
struct msgbuf {
long mtype; /* message type, must be > 0 */
char mtext[MSG_SIZE]; /* message data */
};
int main(void) {
struct msgbuf buf;
int msqid, len;
key_t key;
if ((key = ftok(".", 'a')) == -1) { // 获取键值
perror("ftok");
exit(1);
}
if ((msqid = msgget(key, 0644 | IPC_CREAT)) == -1) { // 获取消息队列标识符
perror("msgget");
exit(1);
}
printf("Enter message to send: ");
fgets(buf.mtext, MSG_SIZE, stdin);
len = strlen(buf.mtext);
if (buf.mtext[len-1] == '\n') {
buf.mtext[len-1] = '\0';
}
buf.mtype = 1; // 消息类型必须大于0
if (msgsnd(msqid, &buf, len+1, 0) == -1) { // 发送消息
perror("msgsnd");
exit(1);
}
printf("Message sent.\n");
if (msgrcv(msqid, &buf, MSG_SIZE, 0, 0) == -1) { // 接收消息
perror("msgrcv");
exit(1);
}
printf("Received message: %s\n", buf.mtext);
if (msgctl(msqid, IPC_RMID, NULL) == -1) { // 删除消息队列
perror("msgctl");
exit(1);
}
return 0;
}
```
该程序首先通过ftok()函数获取一个键值,然后使用msgget()函数获取一个消息队列标识符。接着,它从stdin读取一个消息并将其发送到消息队列中。
在接收方,它使用msgrcv()函数来等待一个消息,并将其存储在buf结构体中。最后,它使用msgctl()函数来删除消息队列。
需要注意的是,消息类型必须大于0,因为消息队列的接收方是按照消息类型来接收消息的。例如,如果一个接收方只接收类型为2的消息,那么它将不会接收到类型为1的消息。
msgctl
msgctl函数是C语言中用来控制消息队列的函数之一,其函数原型为:
```c
#include <sys/msg.h>
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
```
其中,msqid表示消息队列的标识符,cmd表示要执行的操作,buf是一个结构体指针,用于存储或返回消息队列的属性信息。
msgctl函数可以执行多种操作,常用的操作包括:
- IPC_STAT:获取消息队列的属性信息,将其存储在buf所指向的结构体中。
- IPC_SET:设置消息队列的属性信息,使用buf所指向的结构体中的信息进行设置。
- IPC_RMID:删除消息队列。
例如,下面的代码演示了如何使用msgctl函数获取消息队列的属性信息:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/msg.h>
int main()
{
int msqid;
struct msqid_ds msqstat;
// 获取消息队列标识符
if ((msqid = msgget(IPC_PRIVATE, 0666)) == -1)
{
perror("msgget");
exit(1);
}
// 获取消息队列属性信息
if (msgctl(msqid, IPC_STAT, &msqstat) == -1)
{
perror("msgctl");
exit(1);
}
// 打印消息队列属性信息
printf("Message queue %d:\n", msqid);
printf(" Messages: %ld\n", msqstat.msg_qnum);
printf(" Max bytes: %ld\n", msqstat.msg_qbytes);
printf(" PID of last msgsnd: %d\n", msqstat.msg_lspid);
printf(" PID of last msgrcv: %d\n", msqstat.msg_lrpid);
// 删除消息队列
if (msgctl(msqid, IPC_RMID, NULL) == -1)
{
perror("msgctl");
exit(1);
}
return 0;
}
```
该程序首先使用msgget函数创建一个新的消息队列,并获取其标识符。然后,使用msgctl函数执行IPC_STAT操作,获取该消息队列的属性信息,并将其打印输出。最后,使用msgctl函数执行IPC_RMID操作,删除该消息队列。
相关推荐
![c](https://img-home.csdnimg.cn/images/20210720083646.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![xlsx](https://img-home.csdnimg.cn/images/20210720083732.png)