2014-04-17 1 views
0

내가 원하는 것은 : 1 개의 기본 프로세스가 4 개의 하위 프로세스를 생성합니다. -> 기본 프로세스는 하위 프로세스의 메시지를 큐를 통해 수신하고 메시지를 인쇄합니다. -> 아이들은 대기열을 통해 메시지 (우선 순위 + 메시지가있는 문자열)를 보내고 마칩니다. CTRL + C를 누르면 잠시 후 (신호가 자식 코드에 있음) 자식이 끝난 다음 부모가 끝납니다. 현재로서는 mq_send() 및 mq_recieve()에 문제가 있습니다. 내가 wrong¿을 뭐하는 거지, 모두 mq_send()와 mq_receive은() -1 반환 이유를 모르겠어요Fork() 및 Posix 대기열. 보내기 및 받기 문자열

#include <stdlib.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <string.h> 
#include <signal.h> 
#include <sys/wait.h> 
#include <mqueue.h> 

void sigint_handler() 
{ 
    /*do something*/ 
    printf("killing process %d\n",getpid()); 
    exit(0); 
} 

int main() 
{ 

    mqd_t mqd; 

    struct mq_attr atributos; 

//  atributos.mq_maxmsg = 10; 
//  
//  atributos.mq_msgsize = 50; 

    printf ("This is the parent. PID=%d\n",getpid()); 

    int num_children = 4; 

    int i; 
    int pid; 
    int status; 

    char buffer [50]; 

    while (1){ 



    for (i=0; i<num_children ;i++){ 

     if ((pid=fork()==0)){ 

     signal(SIGINT, sigint_handler); 


     int prio = rand() % 3; 

     printf ("%d\n",prio); 

     char * msg= "Hi dude"; 

     char * priority=NULL; 

     if (prio == 0){ 

     priority = "NORMAL"; 

     } 
     else { 

     priority = "URGENT"; 

     } 
     char* toSend=NULL; 

    toSend = malloc(strlen(msg)+1+strlen(priority)); 

     strcpy (toSend,priority); 
     strcat (toSend,msg); 

     printf ("%s\n",toSend); 


     if ((mqd=mq_open("/queue.txt", O_CREAT|O_WRONLY, 0777, &atributos))==-1){ 

     printf ("Error mq_open\n"); 

     exit(-1); 

    } 

    if (mq_send(mqd, msg , strlen(toSend), prio) == -1) { 

     printf ("Error mq_send\n"); 

     exit (-1); 


    } 


     mq_close(mqd); 




    printf ("This is children %d\n",getpid()); 

    sleep(1); 

    exit(0); 

     } 

    } 

    if ((mqd=mq_open("/queue.txt", O_CREAT|O_WRONLY, 0777, &atributos))==-1){ 

     printf ("Error mq_open\n"); 

     exit(-1); 

    } 

    //Rest Parent code 
     if (mq_receive(mqd, buffer, strlen(buffer),0)==-1){ 

     printf ("Error mq_recieve\n"); 

     exit(-1); 

    } 

    printf("Received: %s\n",buffer); 

    sleep (1); 

    waitpid(pid,&status,0); 

    printf ("This is the parent again %d, children should have finished\n",getpid()); 

    mq_close(mqd); 
    } 


} 

: 음, 이건 내 코드? 그리고 내가 말하고있는 오류와 별개로 의도 한 것을하기 위해 내 코드에서 뭔가 잘못 보았습니다. 알려주세요. 미리 감사드립니다. 도움을 주셔서 감사합니다.

+1

읽기 액세스 권한으로 두 번째'mq_open'을 열어야합니다. 예 : 'O_RDONLY' – naab

답변

0

user58697 큰 문제가 발생했습니다.

(1) 할당을 주석 처리했기 때문에 초기화되지 않은 속성을 전달하기 때문에 EINVAL로 대기열이 열리지 않았습니다.

(2) 쓰기 전용으로 두 대기열을 모두 열었습니다. 상위 대기열을 읽기 모드로 열어야했습니다.

(3) 실행 권한은 큐에 아무 것도 의미하지 않으므로 유효하지 않은 777 권한은 필요하지 않습니다.

(4) 길이가 잘못되어 송수신에 실패했습니다. 대부분의 경우, 대부분의 경우 버퍼를 큐의 길이 속성에 할당하는 것이 더 쉽고 안전합니다. 이 경우 길이를 알고 있지만 손에 들지 않는 프로그램에서는 mq_getattr을 통해 값을 얻을 수 있습니다.

(5) rand을 호출하기 전에 srand에 RNG 시드를 지정하지 않았습니다.

(6) 메시지에 공간 (불필요하게)을 할당했지만 결코 해제하지 않은 메모리 누수가 있습니다.

(7) 우선 순위를 전달하면서 무엇을하려했는지는 불필요합니다. POSIX MQ는 우선 순위가 이미 내장되어 있습니다.

나는 fluff (주로 루프 & 신호)의 일부를 프로그램의 큐 측면에 집중 시켰습니다.

#include <stdlib.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <string.h> 
#include <time.h> 
#include <signal.h> 
#include <sys/wait.h> 
#include <mqueue.h> 

int main() 
{ 
    srand(time(NULL)); 

    mqd_t mqd; 

    struct mq_attr atributos = {.mq_maxmsg = 10, .mq_msgsize = 50}; 

    int i; 
    int pid; 
    int status; 
    int num_children = 4; 

    char buffer[atributos.mq_msgsize]; 

    for (i = 0; i < num_children; i++) 
    { 
     if ((pid = fork() == 0)) 
     { 
      int prio = rand() % 3; 

      char* msg = "Hi dude"; 

      strncpy (buffer, msg, sizeof(buffer)); 

      if ((mqd = mq_open("/queue.txt", O_CREAT | O_WRONLY, 0666, &atributos)) == -1) 
      { 
       perror("child mq_open"); 
       exit(1); 
      } 

      if (mq_send(mqd, buffer, sizeof(buffer), prio) == -1) 
      { 
       perror("mq_send"); 
       exit(1); 
      } 

      mq_close(mqd); 

      exit(0); 
     } 

    } 

    // parent 

    if ((mqd = mq_open("/queue.txt", O_CREAT | O_RDONLY, 0666, &atributos)) == -1) 
    { 
     perror("parent mq_open"); 
     exit(1); 
    } 

    int priority; 

    for (int i = 0; i < num_children; ++i) 
    { 
     if (mq_receive(mqd, buffer, sizeof(buffer), &priority) == -1) 
     { 
      perror("mq_recieve"); 
      exit(1); 
     } 

     printf("Received (%s): %s\n", (priority == 0) ? "NORMAL" : "URGENT", buffer); 

     pid_t childpid; 

     if ((childpid = waitpid(-1, &status, 0)) > 0) 
     { 
      if (WIFEXITED(status)) 
       printf("PID %d exited normally. Exit status: %d\n", 
         childpid, WEXITSTATUS(status)); 
      else 
       if (WIFSTOPPED(status)) 
        printf("PID %d was stopped by %d\n", 
          childpid, WSTOPSIG(status)); 
       else 
        if (WIFSIGNALED(status)) 
         printf("PID %d exited due to signal %d\n.", 
           childpid, 
           WTERMSIG(status)); 
     } 
    } 

    mq_close(mqd); 
} 
+0

안녕하십니까, 답변 해 주셔서 대단히 감사합니다. 코드가 명확합니다. int 우선 순위를 부호없는 (unsigned) 우선 순위로 변경하려고 시도했습니다. mq_recieve : Message too long. 크기가 괜찮은 것 같습니다 ... 당신은 어떤 단서가 있습니까? – aDoN

+0

죄송합니다. 두 사람은 서로 관련이 없어야합니다. 그래서 당신이 다른 것을 바꿨다고 생각합니다. – Duck

1

우선 시스템 호출에 실패하면 errno (및 strerror(errno))을 인쇄하십시오.

이제 명백한 실수 : 언급 한 바와 같이

  • , 당신은 mq_receive()
  • strlen(buffer)이 무엇을 할 수 있도록 읽기 액세스를 필요하십니까?
  • 초기화하지 않고 속성을 전달 중입니다.

요약하면 errno을 인쇄하고 잘못된 것을 확인하십시오.