[英]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.