2016-05-04 10 views
0

Ich versuche, fork() zu implementieren, um eine Nachrichtenwarteschlange zu implementieren. Hier ist, was ich habe.Verwendung von fork() falsch?

#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; 
} 

Ich fügte mein tatsächliches Problem hinzu. Hoffentlich ist das nicht zu viel. Dies ist eine Hausaufgabe, aber ich wollte nicht nur Hilfe mit dem Code bekommen. Wieder einmal das einzige Ergebnis, das ich erhalte MESSAGE REC anstatt MESSAGE SENT gefolgt von MESSAGE REC

EDIT:

Okay, Ich habe eine Fehlerprüfung für msq_pid == -1. Ich bemerkte auch, dass ich, als ich meine virtuelle Maschine neu startete, sowohl MESSAGE SENT als auch MESSAGE REC bekommen konnte. Nach mehreren weiteren Durchläufen des Programms begann ich dann nur, MESSAGE REC zu empfangen. Kann jemand das erklären?

+2

Post ein kurzes aber komplettes Programm, das wir kompilieren können, demonstriert das Problem. –

+2

Wenn dieser Code in 'main' ist, sollte es funktionieren (obwohl Sie' \ n' am Ende des ersten 'printf' haben sollten). Wenn Sie es in ein Unterprogramm verschoben haben, haben Sie nicht genügend Code gezeigt. – user3386109

+0

Ich habe das Problem bearbeitet, um alle meine Logik einzuschließen. –

Antwort

2

Per der fork() Man-Seite scheint es Ihr Problem ist, dass Sie das Kind und Eltern invertiert haben. fork() gibt 0 an den untergeordneten Prozess zurück, es gibt> 0 an den übergeordneten Prozess zurück und gibt -1 bei Fehler zurück. Also in Ihrem Code Sie haben sollten:

if(msg_pqid == 0) { 
    /* The child sends the message */ 
} else { 
    /* Parent receives the message */ 
} 

Ich ziehe einen Schalter zu verwenden, etwa so:

switch ((msg_pqid = fork())) { 
case -1: 
    /* Error */ 
case 0: 
    /* Child sends message */ 
default: 
    /* Parent receives message */ 
} 
+0

nicht die Wurzel des Problems. Das Kind kann 'msgrcv()' nicht aufrufen und einige Parameter zu msgget() und msgsnd() sind nicht korrekt. – user3629249

+0

Sie haben Recht, es ist nicht die Wurzel des Problems. Aber er stellt fest, dass dies ein Hausaufgabenproblem ist. Ich entschied mich, seine Zweifel an der Verwendung von 'fork()' auszuräumen, da diese Unsicherheit beseitigt war und er sich darauf konzentrieren konnte, die Wurzel des Problems selbst zu finden. – xmonk

0

mehrere der Systemaufrufe falsch verwendet werden.

Der zurückgegebene Status von mehreren der Systemaufrufe

Der folgende Code ignoriert werden:

  1. sauber
  2. kompiliert die gewünschte Operation durchführt
  3. die Fehler alle Bedingungen Griffe

jetzt der 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