簡體   English   中英

消息隊列。 msgsnd:參數無效

[英]Message queues. msgsnd: Invalid argument

任務是:在指定的數字間隔內查找所有素數,並將其划分為多個范圍。 每個范圍都在生成的過程中處理。 好吧,我真的想成功。 但是出了點問題。 無法理解我的錯誤。 編碼:

#include <stdio.h>
#include <sys/msg.h>
#include <stdlib.h>
#include <unistd.h>
#include <wait.h>
#include <stdbool.h>

#define MAX_SEND_SIZE 50

#define PROCESS_NUMBER 5

struct mymsgbuf {
    long mtype;
    int marray[MAX_SEND_SIZE];
};
typedef struct mymsgbuf type_mymsgbuf;

int msgqid, rc;

void send_message(int qid, type_mymsgbuf* qbuf, long type, int* text, int numbers_per_process) {
    int i;
    int length = sizeof(struct mymsgbuf) - sizeof(long);
    qbuf->mtype = type;
    for (i = 0; i < numbers_per_process; i++) {
        qbuf->marray[i] = text[i];
    }
    if ((msgsnd(qid, (struct msgbuf*)qbuf, (size_t) length, 0)) == -1) {
        perror("msgsnd");
        exit(1);
    }
}

void read_message(int qid, type_mymsgbuf* qbuf, long type, int numbers_per_process) {
    int length = sizeof(struct mymsgbuf) - sizeof(long);
    qbuf->mtype = type;
    msgrcv(qid, (struct msgbuf*)qbuf, (size_t)length, type, 0);
    for (int i = 0; i < numbers_per_process && qbuf->marray[i] != 0; i++) {
        printf("%d\n", qbuf->marray[i]);
    }
}

bool isprime (int a) {
    if(a == 1) {
        return false;
    }
    for (int i = 2; i*i < a; ++i) {
        if ((a % i) == 0) {
            return false;
        }
    }
    return true;
}

int* find_primes_part (int a, int b) {
    int j = 0;
    int* primes = (int*)malloc(sizeof(int)*(b-a));
    for (int k = 0; k < (b-a); ++k) {
        primes[k] = 0;
    }
    for (int i = a; i < b; ++i) {
        if(isprime(i)) {
            primes[j] = i;
            printf("%d\n TEST", primes[j]);
            j++;
        }
    }
    return primes;
}

int find_primes(int a, int b) {
    int status, stat;
    pid_t pid[PROCESS_NUMBER];
    key_t key;
    int qtype = 1;
    type_mymsgbuf qbuf;

    int numbers_per_process = (b-a)/PROCESS_NUMBER;
    if ((key = ftok(".", 'm')) < 0) {
        perror("ftok");
        exit(1);
    }
    if((msgqid = msgget(key, IPC_CREAT|0660)) == -1) {
        perror("msgget");
        exit(1);
    }

    for (int i = 0; i < PROCESS_NUMBER; i++) {
        pid[i] = fork();

        if (-1 == pid[i]) {
            perror("fork");
            exit(1);
        }
        else if (0 == pid[i]) {
            int* part_primes = find_primes_part(a + numbers_per_process*i, a + numbers_per_process*(i+1));
            send_message(msgqid, (type_mymsgbuf*)&qbuf, qtype, part_primes, numbers_per_process);
        }
    }
    for (int j = 0; j < PROCESS_NUMBER; ++j) {
        status = waitpid(pid[j], &stat, 0);
        if (pid[j] == status) {
            if (WEXITSTATUS(stat) != 0) {
                perror("process failed: ");
                exit(1);
            }
        }
    }
    for (int i = 0; i < PROCESS_NUMBER; ++i) {
        read_message(msgqid, &qbuf, qtype, numbers_per_process);
    }

    if ((rc = msgctl(msgqid, IPC_RMID, NULL)) < 0) {
        perror("msgctl");
        return 1;
    }
    return 0;
}

int main() {
    find_primes(10, 200);
    return 0;
}

輸出非常錯誤,並且每隔一段時間就不同。 它類似於:

181
191
193
197
199
163
167
169msgsnd: Invalid argument

173
179
181
191
193
197
msgctl: Invalid argument

主要問題是這2個錯誤

msgsnd: Invalid argument
msgctl: Invalid argument

如何消除它?

我懷疑消息隊列過早被刪除。

問題可能是每個進程(包括子進程)都執行清理代碼。 只有父級應該運行清理代碼。

我想你錯過了return; exit(0); 在客戶端特定代碼中,在調用send_message()

您應該按如下方式完成相應的子進程:

else if (0 == pid[i]) {
    // I'm child
    int* part_primes = find_primes_part(a + numbers_per_process*i, a + numbers_per_process*(i+1));
    send_message(msgqid, (type_mymsgbuf*)&qbuf, qtype, part_primes, numbers_per_process);
    return 0; // --> exit from the child process
}

/* Both parent and child come here if you do not return from child*/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM