不同的Linux消息队列具有相同的ID?

时间:2010-03-07 14:52:27

标签: c linux posix message-queue

我在.c文件中打开一个消息队列,一旦成功就说消息队列id是3.当该程序仍在运行时,在另一个终端中我启动另一个程序(另一个.c文件),具有不同mqd_t的新消息队列。但它的ID也显示为3.这是一个问题吗?

服务器文件是这样的:

void server(char* req_mq) {
struct mq_attr attr;
mqd_t mqdes;
struct request* msgptr;

int n;
char *bufptr;
int buflen;
pid_t apid;

//attr.mq_maxmsg = 300;
//attr.mq_msgsize = 1024;

mqdes = mq_open(req_mq, O_RDWR | O_CREAT, 0666, NULL);
if (mqdes == -1) {
    perror("can not create msg queue\n");
    exit(1);
}
printf("server mq created, mq id = %d\n", (int) mqdes);

,客户端就像:

void client(char* req_mq, int min, int max, char* dir_path_name, char* outfile) {

pid_t pid;

/* get the process id */
if ((pid = getpid()) < 0) {
    perror("unable to get client pid");
}

mqd_t mqd, dq;

char pfx[50] = DQ_PRFX;
char suffix[50]; //
sprintf(suffix, "%d", pid);
strcat(pfx, suffix);

dq = mq_open(pfx, O_RDWR | O_CREAT, 0666, NULL);
if (dq == -1) {
    perror("can not open data queue\n");
    exit(1);
}
printf("data queue created, mq id = %d\n", (int) dq);

mqd = mq_open(req_mq, O_RDWR);
if (mqd == -1) {
    perror("can not open msg queue\n");
    exit(1);
}

mqdes和dq似乎共享相同的ID 3。

3 个答案:

答案 0 :(得分:3)

将句柄视为数组索引。操作系统保存的数组的索引,一个用于系统中的每个进程。

当您打开句柄(对于文件,消息队列,套接字等)时,操作系统会将该对象的设置记录在一个对您的进程唯一的数组中。然后操作系统将索引返回到您的程序中。

每次你的程序使用“处理”操作系统时,操作系统实际上只是查找该私有数组中的结构,它一直在寻找如何处理与该“句柄”相关的对象。

Linux通常分别为STDIN,STDOUT和STDERR保留句柄0,1和2。但从那时起,您打开的任何手柄都将编号为3,4,依此类推。你的句柄3可能与文件“/tmp/foo.txt”有关,而另一个进程的句柄3可能与文件“/tmp/bar.txt”有关。因此,如果两个进程使用类似的文件“句柄”,则无关紧要。

顺便说一句,您不应该知道或关心句柄实际包含的内容。理论上它可以是任何东西 - 一个神奇的数字,一个指针,一个整数,它并不重要。句柄实际上是一个秘密令牌,只要您想要访问系统对象,就可以将其交给操作系统。

答案 1 :(得分:0)

也许你没有关闭第一个消息队列。因为在那种情况下,os给新的一个id(索引)。

答案 2 :(得分:0)

使用mq_open(3)打开消息队列时,消息队列通过您为其提供的名称进行区分。 mq_open(3)返回的消息队列描述符仅在进程范围内有意义。换句话说,另一个进程具有的消息队列描述符值与另一个进程完全无关。这完全类似于文件路径和文件描述符。实际上,Linux的特殊之处在于消息队列描述符实际上是文件描述符 - 请参阅Linux手册页mq_overview(7)。这是您在打开消息队列时看到两个进程获得的公共值3的解释(在最典型的情况下,为了提供STDIN已经打开了0,1,2,{ {1}}和STDOUT之类的STDERR已在他的回答中提到过。)