[英]Using fork() incorrectly?
I'm trying to use fork() to implement a message queue. 我正在尝试使用fork()实现消息队列。 Here's what I've got. 这就是我所拥有的。
#define DATA_SIZE 256
#define BUFF_SIZE 4096
int main(void) {
// seed the random number generator
srand(time(NULL));
// Parent and Ground Truth Buffers
char ground_truth[BUFF_SIZE] = {0}; // used to verify
char producer_buffer[BUFF_SIZE] = {0}; // used by the parent
int i = 0;
int msqid = 0;
int rc;
pid_t msq_pid;
for (i = 0; i < BUFF_SIZE; ++i) {
producer_buffer[i] = ground_truth[i] = rand() % 256;
}
const key_t s_msq_key = 1337; // used to create message queue ipc
const char *const p_msq_key = "/OS_MSG";
msqid = msgget(s_msq_key, IPC_CREAT | 0660);
msq_pid = fork();
if(msq_pid == -1){
perror("error forking");
exit(1);
}
if(msq_pid > 0){
rc = msgsnd(msqid, (void*)p_msq_key, sizeof(producer_buffer), 0);
printf("MESSAGE SENT\n");
if(rc < 0){
perror("message send failed");
exit(1);
}
return 1;
} else {
if(memcmp(producer_buffer, ground_truth, DATA_SIZE) == 0){
printf("MESSAGE REC");
return 1;
}
exit(1);
}
return 0;
}
I added my actual problem. 我添加了我的实际问题。 Hopefully this isn't too much. 希望这不是太多。 This is a homework assignment but I didn't want to just get help with the code. 这是一项家庭作业,但我不想仅仅获得代码方面的帮助。 Once again, the only result that I am getting is MESSAGE REC
rather than MESSAGE SENT
followed by MESSAGE REC
再一次,我得到的唯一结果是MESSAGE REC
而不是MESSAGE SENT
之后是MESSAGE REC
EDIT: 编辑:
Okay, I added an error check for msq_pid == -1
. 好的,我为msq_pid == -1
添加了一个错误检查。 I also noticed that when I restarted my Virtual Machine, I was able to get both MESSAGE SENT
and MESSAGE REC
. 我还注意到,当我重新启动虚拟机时,能够同时收到MESSAGE SENT
和MESSAGE REC
。 After several more runs of the program, I then began only receiving MESSAGE REC
. 在该程序再运行几次之后,我才开始仅接收MESSAGE REC
。 Can someone explain this? 有人可以解释吗?
Per the fork() man page it seems your problem is that you have the child and parent inverted. 在fork()手册页上,似乎您的问题是孩子和父母的关系倒了。 fork() returns 0 to the child process, it returns > 0 to the parent, and returns -1 on error. fork()向子进程返回0,向父进程返回> 0,并在错误时返回-1。 So in your code you should have: 因此,在您的代码中,您应该具有:
if(msg_pqid == 0) {
/* The child sends the message */
} else {
/* Parent receives the message */
}
I prefer to use a switch like so: 我更喜欢使用这样的开关:
switch ((msg_pqid = fork())) {
case -1:
/* Error */
case 0:
/* Child sends message */
default:
/* Parent receives message */
}
several of the system calls are being used incorrectly. 几个系统调用使用不正确。
The returned status from several of the system calls are being ignored 从多个系统调用返回的状态将被忽略
The following code: 如下代码:
now, the code: 现在,代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h> //time()
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h> //fork()
#include <string.h> //memcmp()
#define MAX_MSG_LEN (10)
#define ACT_MSG_LEN (8)
// Parent and Ground Truth Buffers
struct msgbuf
{
long mtype; /* message type, must be > 0 */
char mtext[ MAX_MSG_LEN ]; /* message data */
};
struct msgbuf ground_truth; // used to verify
struct msgbuf producer_buffer = {1,"message"}; // used by the parent
int main(void)
{
// seed the random number generator
srand((unsigned)time(NULL));
//int i = 0;
int msqid = 0;
int rc;
pid_t msq_pid;
ssize_t rcvStatus;
const key_t s_msq_key = 1337; // used to create message queue ipc
//const char *const p_msq_key = "/OS_MSG";
msqid = msgget(s_msq_key, IPC_CREAT | 0660);
if( -1 == msqid )
{// then msgget failed
perror( "msgget failed");
exit( EXIT_FAILURE );
}
// implied else, msgget successful
msq_pid = fork();
while(1)
{
switch( msq_pid )
{
case -1:
perror("error forking");
exit( EXIT_FAILURE );
break;
default: // parent process
rc = msgsnd(msqid, &producer_buffer, sizeof producer_buffer, 0);
printf("MESSAGE SENT: %s\n", producer_buffer.mtext);
if(rc < 0)
{
perror("message send failed");
exit( EXIT_FAILURE );
}
break;
case 0: // child process
rcvStatus = msgrcv( msqid, &ground_truth, sizeof( ground_truth ), 0, 0);
if( -1 == rcvStatus )
{ // then msgrcv failed
perror( "msgrcv failed" );
exit( EXIT_FAILURE );
}
// implied else, msgrcv successful
if(memcmp(producer_buffer.mtext, ground_truth.mtext, ACT_MSG_LEN) == 0)
{
printf("MESSAGE REC %s\n", ground_truth.mtext);
}
else
{
printf( "msg Sent: '%s' does not match msg Recv: '%s'\n", producer_buffer.mtext, ground_truth.mtext);
}
break;
} // end switch
} // end while forever
} // end function: main
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.