【问题标题】:How to run the following message queue on Linux?如何在 Linux 上运行以下消息队列?
【发布时间】:2018-12-10 16:56:57
【问题描述】:

银河帝国计划派遣一艘星际驱逐舰攻击叛军的基地。这艘歼星舰将容纳1024名帝国克隆战士。

t=0 只有一名士兵可用:队长。从他的第一个生日开始,克隆战士可以每年克隆一次。大帝想在短时间内让歼星舰准备好行动。

帝国指挥结构很简单:

  • 每个战士都会向他的克隆人发送命令
  • 没有与上级沟通

编写具有以下要求的 Linux C 程序:

  • 每个克隆战士都必须由一个单独的进程表示
  • 必须通过唯一 (!) 命名的消息队列传输命令 *从Imperator到船长有一个现有的消息队列/Imperator
  • 克隆阶段结束后,每个克隆战士都必须等待命令接收并传递给他的下级

提示和要求:

  • 考虑一下,哪一年有多少士兵可用:t=0——只是上尉,t=1——上尉和他的第一个克隆人,等等。
  • 不用担心错误处理

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h>
#include <sys/stat.h> 
#include <mqueue.h> 
#include <errno.h>

// Exercise „clone warriors“
#define NUM 10
#define SIZE_MSGBUF 500
#define MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH |S_IWOTH)

mqd_t QueueArray[NUM]; // queues to my clones
void cleanQueueArray(void) { // support function for init: start with no queues
    for (int i=0; i<NUM; i++) QueueArray[i] = 0;
}

int main(void) {
    char cNameBossQueue[100] = "/Imperator"; // boss queue‘s default name
    mqd_t BossQueue; // boss queue to receive commands of the father‘s process

    struct mq_attr attr;
    attr.mq_maxmsg = 10;
    attr.mq_msgsize = SIZE_MSGBUF;
    attr.mq_flags = 0;

    int nPrio=0;
    char cMsgbuf[SIZE_MSGBUF+1] = "";

    cleanQueueArray(); // init: no queues to any clones at the beginning

    // phase 1 / clone phase takes NUM years:
    for (int i=0; i<NUM; i++) {
        pid_t npid_child = fork();
        if (npid_child > 0) { // Father. Create + store command channel to clone:
            char cQueue[100];
            sprintf(cQueue, "/Queue%d", npid_child);
            QueueArray[i] = mq_open(cQueue, O_CREAT|O_WRONLY, MODE, &attr);
        } else { // Child. Remember the name of the boss queue:
            sprintf(cNameBossQueue, "/Queue%d", getpid());
            cleanQueueArray(); // Child has no queues to clones currently
        }
    }

    // Phase 2 / battle phase. Receive and transmit orders:
    BossQueue = mq_open(cNameBossQueue, O_RDONLY, MODE, &attr);
    mq_receive(BossQueue, cMsgbuf, SIZE_MSGBUF, &nPrio);

    // Send orders to all of my clones:
    for (int i=0; i<NUM; i++) {
        if (QueueArray[i] > 0) {
            mq_send (QueueArray[i], cMsgbuf, strlen(cMsgbuf), 0);
        }
    }

    // Cleanup work...
    return 0;
}

我尝试使用

运行它
gcc -o Wall clonew clonew.c -lrt"
./clonew

但我没有得到任何输出

【问题讨论】:

  • 虽然机器可以轻松阅读代码,但对于人类来说,适当的缩进可能会有所帮助。
  • 我希望gcc -Wall -o clonew clonew.c -lrt 有更多的东西。你能解释一下你在显示的命令行背后的想法吗?
  • 尝试启动./Wall,看看是否有输出;)

标签: c linux process operating-system fork


【解决方案1】:

你的命令行(没有尾随的",我认为这是一个发布意外)

gcc -o Wall clonew clonew.c -lrt

意思

  • 编译 clonew 和 clonew.c
  • 到名为“Wall”的可执行文件中
  • 使用 rt 库

我不确定为什么使用“clonew”(首先在编译命令中,稍后在执行尝试中)不会触发任何警告。 显然,您打算创建并执行该文件。但它被用作输入文件,即使它存在但不是 C 语法文件,也应该引起一些抱怨。

但是,当您尝试执行 clonew 时没有得到预期的输出的原因是您的编译命令不能导致创建可执行的 clonew。

为什么尝试执行某些尚不存在或为 C 代码文件的东西不会导致任何警告、错误或任何其他输出,这是一个谜。

如果它已经作为可执行但静默程序存在,它也应该触发投诉。

【讨论】:

    猜你喜欢
    • 2018-01-16
    • 2019-03-17
    • 1970-01-01
    • 2011-11-04
    • 1970-01-01
    • 2010-12-24
    • 2021-10-01
    • 2018-01-20
    • 1970-01-01
    相关资源
    最近更新 更多