2013-01-22 86 views
0

我想用shm_unlink(object_path)來清除我在信號處理函數中打開的共享內存。但是,代碼不起作用。出了什麼問題?代碼基本上這樣做:父進程從用戶輸入中取兩個整數,然後派生一個孩子來計算兩者的總和。計算總和後,孩子通知父母它已通過管道計算總和。當接收到SIGINT信號時,孩子不應該自行終止,它應該讓父進程處理信號,然後父進程發送一個SIGKILL信號來終止子進程。 謝謝!shm_unlink說「沒有這樣的文件或目錄」

#include <sys/mman.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include <fcntl.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <signal.h> 


#define SHARED_OBJECT_PATH   "/shared_memory" 
#define READ_END 0 
#define WRITE_END 1 
#define BUFFER_SIZE 1 
//Global Variables 
int pid; //Child Process ID 

void signal_callback_handler(int signum){ 
    if (signum == SIGINT){ 
     printf("I am %d and I am handling SIGINT. \n", getpid()); /* process ID that's handling SIGINT */ 
     kill(pid,SIGKILL); 
     if (shm_unlink(SHARED_OBJECT_PATH) != 0) { 
      perror("In shm_unlink()"); 
      exit(1); 
     } 
    } 
} 
int main(int argc, char *argv[]){ 
    int fd,status; 
    int pfd1[2],pfd2[2]; /*Two communication channels will be created. pfd1 for parent->child, pfd2 child->parent*/ 
    char msg[BUFFER_SIZE]; 
    int first_num, second_num, sum; 

    int shared_seg_size = 3*(sizeof(int)); 
    int *shared_msg; /* We want a shared segment capable of storing 2 integers and 1 sum */ 

    if(pipe(pfd1) < 0 || pipe(pfd2) < 0){ 
     printf("Failed to create a pipe between parent and child \n"); 
     exit(-1); 
    } 


    /* Open the Shared Memory Segment */  
    fd = shm_open(SHARED_OBJECT_PATH, O_CREAT | O_EXCL | O_RDWR, S_IRWXU | S_IRWXG); 
    if (fd < 0) { 
     perror("In shm_open()"); 
     exit(1); 
    } 
    fprintf(stderr, "Created shared memory object %s\n", SHARED_OBJECT_PATH); 
    /* Adjust mapped file size (make room for the whole segment to map) using ftruncate() */ 
    ftruncate(fd, shared_seg_size); 
    /* Request the shared segment using mmap() */  
    shared_msg = (int *) mmap(NULL, shared_seg_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 
    if (shared_msg == NULL) { 
     perror("In mmap()"); 
     exit(1); 
    } 
    fprintf(stderr, "Shared memory segment allocated correctly (%d bytes).\n", shared_seg_size); 
    /*End of the opening of the Shared Memory Segment */ 

    if((pid = fork()) < 0){ /* Fork the process */ 
     printf("Fork error \n"); 
     exit(-1); 
    } 
    else if (pid > 0){/* Parent code */ 
     signal(SIGINT, signal_callback_handler); /* To handle the Ctrl+C signal and clean up shared memory */ 
     close(pfd1[READ_END]); 
     close(pfd2[WRITE_END]); 

     while(1){ /* Keep running the main process to get user input */ 
      printf("Enter the first number: "); 
      scanf("%d",&first_num); 
      printf("Enter the second number: "); 
      scanf("%d",&second_num); 

      /* Write the two integers to the shared memory segment */ 
      shared_msg[0] = first_num; 
      shared_msg[1] = second_num; 

      msg[0] = '1'; /*Write to the pipe and tell child to compute the sum */ 
      write(pfd1[WRITE_END], msg, BUFFER_SIZE); 
      read(pfd2[READ_END],msg, BUFFER_SIZE); 
      if (msg[0] == '1'){   
       sum = shared_msg[2]; 
       printf("The sum is %d\n",sum); 
       msg[0] = '0'; /*Tell the child to get ready to compute new sum*/ 
       write(pfd1[WRITE_END],msg,BUFFER_SIZE); 
      } 
     } 
    } 
    else if (pid == 0){/* Child Code */ 
     close(pfd1[WRITE_END]); 
     close(pfd2[READ_END]); 

     while(1){ 
      read(pfd1[READ_END],msg,BUFFER_SIZE); 
      if (msg[0] == '1'){ /*Child should compute sum*/ 
       sum = shared_msg[0]+shared_msg[1]; 
       shared_msg[2] = sum;  
       msg[0] = '1'; /*Tell the parent, the sum is computed */ 
       write(pfd2[WRITE_END],msg,BUFFER_SIZE); 
      } 
     } 
    } 
} 

回答

1

我試過了你的代碼。更改此:

if (shm_unlink(SHARED_OBJECT_PATH) != 0) { 
     perror("In shm_unlink()"); 
     exit(1); 
    } 

if (shm_unlink(SHARED_OBJECT_PATH) != 0) { 
     perror("In shm_unlink()"); 
     exit(1); 
    } 
    else { 
     perror("All right!"); 
     exit(0); 
    } 

否則需要兩個Ctrl + C退出......第一去除共享內存,第二讓你的程序退出,因爲shm_unlink()返回一個錯誤(原因shmem先前被刪除的第一個Ctrl + c)

+0

shm_unlink和exit都從大多數信號處理上下文無效,包括這一個。 –

+0

我認爲這只是不安全。無效。否則,你介意解釋一下嗎? –

+0

從異步信號的信號處理函數中調用非異步信號安全函數,除非在非異步信號安全函數期間不能調用處理程序,否則它是UB。 –

相關問題