2014-11-04 92 views
0

我想通過使用共享內存來共享信號到所有進程。 首先,我將對象「sem」映射到父進程中的共享內存。 分叉過程之後,我正在做同樣的事情,但在子進程的地址空間中使用「sem」。 它應該在所有進程的共享內存中使用一個信號量,但它不起作用。共享信號量出錯。我不能使用命名的信號量。將信號量共享到進程

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

void doSomething(); 
void shareSem(); 
void recieveSem(); 

sem_t sem; 

int main(int argc, char *argv[]) { 
    shareSem(); 
    sem_init(&sem, 1, 1); 



    for(int i = 0; i < 1; i++){ 
      int pid = fork(); 
      if(pid == 0) 
        recieveSem(); 
    }; 
    doSomething(); 


return 0; 
} 

void doSomething() { 
int i, time; 
for (i = 0; i < 3; i++) { 

    // P operation 
    if (sem_wait(&sem) == 0) { 

     // generate random amount of time (< 30 seconds) 
     time = (int) ((double) rand()/RAND_MAX * 5); 

     printf("Process %i enters and sleeps for %d seconds...\n", getpid(), time); 

     sleep(time); 

     printf("Process %i leaves the critical section\n", getpid()); 

     // V operation 
     sem_post(&sem); 
    } 
    else 
     printf("Process id: %d :error\n", getpid()); 
} 
} 

void shareSem() 
{ 
    int fd, status; 
    fd = shm_open("/swp_es", O_RDWR | O_CREAT, 0777); 
    if(fd == -1) { 
      printf("shm_creator1"); 
    } 
    status = ftruncate(fd, sizeof(sem)); 
    if(status != 0) { 
      printf("shm_creator2"); 
    } 
    void *ptr = mmap(&sem, sizeof(sem), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 
    if(ptr == MAP_FAILED) { 
      printf("shm_creator3"); 
    } 
} 

void recieveSem() 
{ 
    int fd; 
    fd = shm_open("/swp_es", O_RDWR, 0777); 
    if(fd == -1) { 
      printf("shm_user"); 
    } 
    void *ptr = mmap(&sem, sizeof(sem), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 
    if(ptr == MAP_FAILED) { 
      printf("shm_user"); 
    }  

    //munmap(buffer, sizeof(buffer)); 
} 

結果是:

Process 4534308 enters and sleeps for 2 seconds... 
Process id: 4534309 :error 
Process id: 4534309 :error 
Process id: 4534309 :error 
Process 4534308 leaves the critical section 
Process 4534308 enters and sleeps for 0 seconds... 
Process 4534308 leaves the critical section 
Process 4534308 enters and sleeps for 1 seconds... 
Process 4534308 leaves the critical section 

回答

0

你缺少一個mmap()不一定共享內存段映射到你給的具體地址。此外,在某些系統中,地址具有特定的對齊要求,如果您提供的指針不滿足要求,則mmap()將失敗。通過NULL作爲地址,並且讓系統選擇,便攜性更強。然後,無論系統選擇哪個位置,都將信號量放在那裏。

另外,你讓它太難了。如果你的子進程是fork(),那麼它會繼承父進程的內存映射。您不必重新創建它們。

例子:

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/mman.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <semaphore.h> 

void doSomething(sem_t *sem); 

int main(int argc, char *argv[]) { 
    int shm_fd = shm_open("/swp_es", O_RDWR | O_CREAT, 0600); 
    sem_t *sem; 
    int i; 

    if (shm_fd == -1) { 
     printf("Failed to create/open a shared memory object\n"); 
     return 1; 
    } 
    if (ftruncate(shm_fd, sizeof(*sem)) != 0) { 
     printf("Failed to resize the shared memory object\n"); 
     return 1; 
    } 
    sem = mmap(NULL, sizeof(*sem), PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); 
    if(sem == MAP_FAILED) { 
     printf("Failed to mmap() the shared memory object\n"); 
     return 1; 
    } 

    /* It's safe to unlink once the shared memory is mapped */ 
    if (shm_unlink("/swp_es") < 0) { 
     printf("warning: failed to unlink the shared memory object\n"); 
    } 

    if (sem_init(sem, 1, 1) != 0) { 
     printf("Failed to initialize the semaphore\n"); 
     return 1; 
    } 

    for(i = 0; i < 1; i++){ 
     int pid = fork(); 

     if (pid < 0) { 
      printf("Failed to fork()\n"); 
      return 1; 
     } else if (pid == 0) { 
      printf("Child %d successfully fork()ed\n", i); 
     } 
    }; 
    doSomething(sem); 

    return 0; 
} 

void doSomething(sem_t *sem) { 
    int i; 

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

     if (sem_wait(sem) == 0) { 
      int time = (int) (rand()/(RAND_MAX * 5.0)); 

      printf("Process %i enters and sleeps for %d seconds...\n", getpid(), time); 
      sleep(time); 
      printf("Process %i leaves the critical section\n", getpid()); 

      sem_post(sem); 
     } 
     else { 
      printf("Process id: %d :error in sem_wait()\n", getpid()); 
      break; 
     } 
    } 
} 
+0

謝謝你,它的工作。 – Stark 2014-11-05 12:35:52