プログラムは2つの子プロセスを作成します。最初の子プロセス(1)は、stdinからテキストを読み取り、特別な文字を削除して、単語に分割します。プログラムのその部分は問題なく機能します。次に、子(1)が単語を分割している間、メッセージキューを介して各単語全体を送信します。この部分により、無効な引数エラーが発生します。子2は、画面に戻ってきたメッセージを印刷するだけです。
少なくとも、それが私がこの作業を計画した方法です。私はちょっと立ち往生していて、メッセージキューをデバッグする方法がよくわかりません。今、それはからエラーを投げています
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <error.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <ctype.h>
# define QUEUE_PERMS 0644
static int message_queue = (int) 0;
static key_t key = (key_t) 0;
typedef struct message
{
long mtype;
char msg[100];
} mess_t;
int main(int argc, char *argv[]){
const char delimiters[] = " ,.-!?()1234567890@#$%^&*\n";
char *word = NULL;
size_t buffer = 100;
char *token;
mess_t message;
mess_t message2;
int i;
// set up a message queue
key = ftok(__FILE__,'x');
// create queue
message_queue = msgget(key, QUEUE_PERMS | IPC_CREAT);
if(message_queue == -1){
perror("creating message queue");
}
// create parcer process. This tokenizes the strings
// and send each work to the sort function(s)
switch(fork()){
case 0:
// child process # 1 starts here
key = ftok(__FILE__,'x');
message_queue = msgget(key, QUEUE_PERMS);
// splitting the words up here, this works fine
while(getline(&word, &buffer, stdin) != EOF){
token = strtok(word, delimiters);
while(token != NULL){
for(i = 0; token[i]; i++){
token[i] = tolower(token[i]);
}
// set type to 1 to send
message.mtype = 1;
// copy the word (token) over to the message struct
strcpy(message.msg,token);
// **** I get a send failed: Invalid argument here *****
if(msgsnd(key, &message, sizeof(message), MSG_NOERROR) == -1){
perror("send failed");
}
token = strtok(NULL, delimiters);
}
}
break;
case -1:
perror("error fork\n");
break;
default:
wait(NULL);
break;
}
// this process should read the message an print it out
switch(fork()){
case 0:
// child process # 2 starts here
key = ftok(__FILE__,'x');
message_queue = msgget(key, QUEUE_PERMS );
msgrcv(key, &message2, sizeof(message),1, MSG_NOERROR);
printf("child process got %s\n", message2.msg);
break;
case -1:
perror("error fork\n");
break;
default:
wait(NULL);
break;
}
return 0;
}
message_queue
メッセージキューIDをmsgget()
で設定しますが、メッセージキューIDmsgsnd()
のkey
代わりにを使用して送信しようとします。
あなたも同じ問題を抱えていmsgrcv()
ます。
これら2つを修正すると、プログラムを実行できます。
$ ./mq
abelone apathy
child process got abelone
child process got apathy
$
abelone apathy
1行で入力してControl-Dから、EOFを示します。
整理すると、読み取りプロセスが有効になる前に、書き込みプロセスがメッセージキューを埋めます。入力が大きすぎない限り、それは機能します。ただし、実際には2つのプロセスを同時に実行する必要があります。wait()
並行性を与えるには、呼び出しを移動する必要があります。(コードを関数に適切に分離することのもう1つの利点—可能な限り非表示にすると、そのような問題を見つけやすくなります。)
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加