使用消息队列API Linux在父子进程之间发送密钥

问题描述 投票:0回答:1

此程序使用两个过程移动汽车('*'标记)。

父母从用户读取按键并将其发送给孩子。

孩子根据从父母那里收到的钥匙移动汽车。

移动:箭头键(向左,向上,向右,向下)

停止:空格键

退出:“ q”

我正在尝试使用Linux消息队列API完成该程序。

但是我收到类似的错误消息>

msgrcv:无效参数

并且该程序无法正常工作。有人可以帮我解决问题吗?我认为其余的代码都很好,但是我在发送和接收消息时遇到问题。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h>

#include "Console.h"

#define TRUE 1
#define FALSE 0

typedef struct {        
    long data_type;
    int key; 
} Message;

Message msg;

void Controller(int msgq);
void MoveCar(int msgq);

int main()
{
    int msgq = 0;   // id of message queue
    key_t msgkey;
    //Create a message queue (msgq)
    //      On failure, print an error message and exit.
    if ((msgq = msgget(msgkey, IPC_CREAT | 0666) == -1)) {
        perror ("msgget");
        exit (1);
    }


    clrscr();
    gotoxy(1, 1);
    printf("Move the car with the arrow keys, space(stop), or q(quit).\n");


    pid_t parent, child;
    int status;


    // Create a child process
    child = fork();
    if (child == -1)
    {
        // fork() returns -1 on failure
        perror("fork");
        return (-1);
    }


    // On the child process
        // Call MoveCar(msgq) 

    else if (child == 0)
    {
        MoveCar(msgq);
    }
    // On the parent process
        // Call Controller(msgq)
        // Wait for the child process
        // Remove the message queue

   else
    {

        do{
            Controller(msgq);
            parent = wait(&status);
        } while(parent != child);

        if (msgctl(msgq, IPC_RMID, 0) == -1) {
            perror ("msgctl");
            exit (1);
    }

    }


    return 0;
}

void Controller(int msgq)
{
    // Repeat until the user types 'q'
        // Read a key using getch()
        // Send the key through msgq 
        //      On failure, print an error message.

    int press;

    while(press == 'q'){  

        press = getch();

        //Send the message to snd_queue
        msg.key = press;

        if (msgsnd (msgq, &msg, sizeof(Message msg), 0) == -1) {  
            perror ("msgsnd ");
            exit (1);
        }
    }

}

void MoveCar(int msgq)
{
    int width = getWindowWidth();
    int height = getWindowHeight() - 1;

    int x = width / 2;
    int y = height / 2;
    int dx = 0;
    int dy = 0;


    EnableCursor(FALSE);

    // initially, draw car at the center
    gotoxy(x, y);
    putchar('*');
    fflush(stdout);

    int repeat = 1;
    while(repeat){
        int ret = 0;
        int key = 0;

        // Receive the key from msgq
        msg.data_type = 0;
        ret = msgrcv(msgq, &msg, sizeof(msg), msg.data_type, IPC_NOWAIT);

        if ( ret== -1) {
            perror ("msgrcv");
            exit (1);
        }

        key = msg.key;

        if(ret > 0){        // if a key was received
            gotoxy(1, height);
            printf("ret = %d, key = %d (%c) ", ret, key, key); 
            fflush(stdout);

            // set direction according to the key
            switch(key){
                case ' ':           // space
                    dx = dy = 0;
                    break;

                case 68:            // left
                    dx = -1;
                    dy = 0;
                    break;

                case 65:            // up
                    dx = 0;
                    dy = -1;
                    break;

                case 67:            // right
                    dx = 1;
                    dy = 0;
                    break;

                case 66:            // down
                    dx = 0;
                    dy = 1;
                    break;

                case 'q':
                    repeat = 0;
                    break;
            }
        }

        // erase previous coordinate
        gotoxy(x, y);
        putchar(' ');

        // update coordinate
        x += dx;
        if(x < 1){
            x = 1;
            dx = 0;
        } else if(x > width){
            x = width;
            dx = 0;
        }

        y += dy;
        if(y < 1){
            y = 1;
            dy = 0;
        } else if(y > height){
            y = height;
            dy = 0;
        }

        // draw star at the new coordinate
        gotoxy(x, y);
        putchar('*');

        gotoxy(width - 2, 1);

        fflush(stdout);
        MySleep(50);
    }

    EnableCursor(TRUE);

    clrscr();
    gotoxy(1, 1);
    printf("Bye!\n");
}


此程序使用两个过程移动汽车('*'标记)。父母从用户读取按键并将其发送给孩子。孩子根据从父母那里收到的钥匙移动汽车。 ...

c linux process fork message
1个回答
© www.soinside.com 2019 - 2024. All rights reserved.