我正在测试运行在同一台机器上的两个C程序之间的IPC示例(来自here).以下是消息作者和读者的两条主线:

Bar.c(作者)

// bar.c -- C Program for Message Queue (Writer Process)
#include <cstdio>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <cstring>

using namespace std;

// structure for message queue
struct mesg_buffer {
   long mtype;
   char mtext[100];
};

int main()
{
   mesg_buffer message;
   message.mtype = 1;
   strcpy(message.mtext, "Hello Process!");

   // ftok to generate unique key
   key_t key = ftok("dummy.txt", 65);
   if (key < 0)
      printf("Bad key!\n");

   // msgget creates a message queue and returns identifier
   int msgid = msgget(key, 0666 | IPC_CREAT);

   // msgsnd to send message and echo to console:
   msgsnd(msgid, &message, sizeof(message), 0);
   printf("Data send is : %s \n", message.mtext);
   return 0;
}

Foo.c(阅读器)

// foo.c -- C Program for Message Queue (Reader Process)
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/msg.h>

// structure for message queue
struct mesg_buffer {
   long mtype;
   char mtext[100];
};

int main()
{
   mesg_buffer message;

   // ftok to generate unique key
   key_t key = ftok("dummy.txt", 65);
   if (key < 0)
      printf("Bad key!\n");

   // msgget creates a message queue and returns identifier
   int msgid = msgget(key, 0666 | IPC_CREAT);

   // msgrcv to receive message
   msgrcv(msgid, &message, sizeof(message), 1, 0);
   printf("Data Received is : %s \n", message.mtext);

   // to destroy the message queue
   msgctl(msgid, IPC_RMID, NULL);
   return 0;
}

我运行了这两个程序,但出现了"Bad Key"错误,因为我的文件系统上没有"ummy.txt".尽管如此,程序仍在继续,我得到了一个很好的IPC:

penelope:~/test/build/bin$ ./bar
Bad key!
Data send is : Hello Process! 

和在单独的终端中:

penelope:~/test/build/bin$ ./foo 
Bad key!
Data Received is : Hello Process! 

因此,即使有键错误,我也成功地进行了IPC.

现在我定义了dummy.txt(我不知道我为什么需要它),然后再次运行这对.foobar运行时没有"Bad Key"错误,但foo挂起等待通信.

为了努力理解ftok在做什么,我将这些行改为以下几行:

巴.c:key_t key = ftok(nullptr, 66);

Foo.c:key_t key = ftok(nullptr, 65);&lt;--注意不同的索引

我在两者中都得到了"Bad Key"错误,但IPC工作正常.这是怎么回事?如果ftok键在程序中甚至都不是有效的,这两个进程在这里如何通信?当 keys 看起来有效时,它就不起作用了吗?

推荐答案

如果您查看glibc源代码,您会发现如果您没有提供有效的文件,则ftok返回-1:

#include <sys/ipc.h>
#include <sys/stat.h>

key_t
ftok (const char *pathname, int proj_id)
{
  struct __stat64_t64 st;
  key_t key;

  if (__stat64_time64 (pathname, &st) < 0)
    return (key_t) -1;

  key = ((st.st_ino & 0xffff) | ((st.st_dev & 0xff) << 16)
     | ((proj_id & 0xff) << 24));

  return key;
}

如果没有ftok密钥,这两个进程在这里如何通信 甚至在节目中有效吗?

该函数返回-1以通知您发生了错误,但不会阻止将其用作(坏的)键.简而言之,该密钥将与所有滥用该函数的程序发生冲突,但两个进程都会通信,因为它们使用的是同一个密钥.

C++相关问答推荐

如何确保内存分配在地址附近?

带双指针的2D数组

DPDK-DumpCap不捕获端口上的传入数据包

自定义应用程序上的日志(log)轮换问题

显式地将值转换为它从函数返回的类型的含义是什么?

空指针的运行时强制转换

为什么net/if.h在ifaddrs.h之前?

C是否用0填充多维数组的其余部分?

双指针指向常量双指针的指针类型赋值不兼容

错误:包含文件时类型名称未知

不同出处的指针可以相等吗?

GCC奇怪的行为,有fork 和印花,有换行符和不换行符

在C中创建任意类型的只读指针参数

搜索使用int代替time_t的用法

Zlib:解压缩大文件导致";无效代码长度设置";错误

使用Open62541向OPCUA服务器发送读请求时内存泄漏

S,在 struct 中创建匿名静态缓冲区的最佳方式是什么?

我错误地修复了一个错误,想了解原因

'printf("%s", user_input)' 危险吗?

可以从指针数组中的值初始化指针吗?