C语言消息队列实现进程通信


通过消息队列实现进程的通信

ftokmsgget创建消息队列的关键函数。

  1. ftok函数:

    • ftok函数用于将文件路径和一个整数标识符(通常是一个字符)转换为一个唯一的键值(key)。它的原型如下:
      key_t ftok(const char *pathname, int proj_id);
    • pathname是一个指向文件的路径的字符串。通常,你可以创建一个独立的文件,用于生成唯一的键值。
    • proj_id是一个用户定义的整数标识符,用于进一步区分不同的消息队列。通常使用一个字符来表示。
    • ftok函数根据pathnameproj_id生成一个唯一的键值,并返回该键值。
  2. msgget函数:

    • msgget函数用于创建或获取消息队列的标识符(msgid)。它的原型如下:
      int msgget(key_t key, int msgflg);
    • key是通过ftok函数生成的唯一键值,用于识别特定的消息队列。
    • msgflg是一个标志参数,用于指定消息队列的创建和访问权限。可以使用位运算符将多个标志组合在一起。常用的标志包括:
      • IPC_CREAT:如果消息队列不存在,则创建一个新的消息队列。
      • IPC_EXCL:与IPC_CREAT一起使用,用于确保创建一个新的消息队列,如果消息队列已经存在则返回错误。
      • 权限标志:用于指定消息队列的访问权限,例如0666表示所有用户都具有读写权限。
    • msgget函数返回一个用于标识消息队列的整数值(msgid)。你可以使用这个msgid来进行后续的消息发送和接收操作。

通过调用ftok函数生成唯一的键值,并将该键值传递给msgget函数,你可以创建或获取一个特定的消息队列,并获得与之关联的msgid。

msgsndmsgrcv发送和接受消息

当使用System V消息队列进行进程间通信时,msgsndmsgrcv是用于发送和接收消息的关键函数。

  1. msgsnd函数:

    • msgsnd函数用于向消息队列发送消息。它的原型如下:
      int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
    • msqid是消息队列的标识符,即通过msgget函数获取到的msgid。
    • msgp是一个指向消息数据的指针,通常是一个自定义的结构体指针。你可以定义一个结构体来存储消息的类型和内容等信息。
    • msgsz是消息的大小,以字节为单位。你需要确保msgsz与实际发送的消息大小相匹配。
    • msgflg是一个标志参数,用于指定发送消息的行为。常用的标志包括:
      • IPC_NOWAIT:如果消息队列已满,不要等待,立即返回错误。
      • 0:阻塞发送,如果消息队列已满则等待直到有空间可用。
    • msgsnd函数返回一个整数值,表示消息发送的结果。如果成功发送消息,则返回0;如果出现错误,则返回-1。
  2. msgrcv函数:

    • msgrcv函数用于从消息队列接收消息。它的原型如下:
      ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
    • msqid是消息队列的标识符,即通过msgget函数获取到的msgid。
    • msgp是一个指向接收消息的缓冲区的指针,通常是一个自定义的结构体指针,用于存储接收到的消息数据。
    • msgsz是接收缓冲区的大小,以字节为单位。你需要确保msgsz足够大以容纳接收的消息。
    • msgtyp是消息类型,用于指定接收消息的条件。通常,你可以使用一个特定的值来筛选消息类型,例如,只接收特定类型的消息。
    • msgflg是一个标志参数,用于指定接收消息的行为。常用的标志包括:
      • IPC_NOWAIT:如果消息队列为空,不要等待,立即返回错误。
      • 0:阻塞接收,如果消息队列为空则等待直到有消息可用。
    • msgrcv函数返回一个整数值,表示接收消息的结果。如果成功接收消息,则返回接收到的消息的长度;如果出现错误,则返回-1。

这两个函数提供了发送和接收消息的基本功能,你可以根据需要进行调用和处理接收到的消息。记住,发送和接收消息的进程需要拥有对消息队列的适当权限。

样例

#include <cstring>
#include <iostream>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <unistd.h> // fork
// 定义消息结构体
struct Message {
    long mtype;
    char mtext[100];
};

int main() {
    key_t key;
    int msgid;
    Message msg;

    // 生成唯一的key
    key = ftok("message_queue_example", 65);

    // 创建消息队列
    msgid = msgget(key, 0666 | IPC_CREAT);

    // 发送消息的进程
    if (fork() == 0) {
        // 子进程发送消息
        printf("子进程发送消息\n");
        msg.mtype = 1;
        strcpy(msg.mtext, "Hello from child process!");
        msgsnd(msgid, &msg, sizeof(msg.mtext), 0);
    } else {

        // 父进程接收消息
        msgrcv(msgid, &msg, sizeof(msg.mtext), 1, 0);
        std::cout << "Received message: " << msg.mtext << std::endl;
        // 删除消息队列
        std::cout << "end" << std::endl;
        msgctl(msgid, IPC_RMID, nullptr);
    }
    return 0;

Author: Acaibird
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint policy. If reproduced, please indicate source Acaibird !
  TOC