2015-10-20 74 views
0

我想同步兩個處理程序讀取和寫入共享內存。這裏是a_process.c如何在c上使用posix命名信號與linux上兩個進程之間的共享內存?

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

#define SHM_PATH  "/instant_messaging" 
#define SHM_SIZE   50 
#define SEM_PATH  "/sem_instant_messaging" 

char *sendbuff; 

int main() 
{ 
    //sahred memory setting 
    //shm_unlink(SHM_PATH); 
    int shmfd; 

    shmfd = shm_open(SHM_PATH, O_CREAT | O_RDWR, S_IRWXU | S_IRWXG); 
    if (shmfd < 0) { 
     perror("In shm_open()"); 
     exit(1); 
    } 

    int shm_size = SHM_SIZE; 

    ftruncate(shmfd, shm_size); 
    sendbuff = (char*) mmap(NULL, shm_size, PROT_READ | PROT_WRITE, 
      MAP_SHARED, shmfd, 0); 
    if (sendbuff == NULL) { 
     perror("In mmap()"); 
     exit(1); 
    } 

    //semaphore setting 
    sem_unlink(SEM_PATH); 

    sem_t * sem1; 

    sem1 = sem_open(SEM_PATH, O_CREAT, S_IRUSR | S_IWUSR, 1); 
    printf("before while\n"); 
    //setmemshr(); 
    //setsem(); 
    while (1) { 
     int status = sem_wait(sem1); 

     if (status != 0) 
     { 
      perror("in sem_wait"); 
     } 
     printf("after wait\n"); 
     printf("%s\n",sendbuff); 
     scanf("%s",sendbuff); 
     sem_post(sem1); 
     //sleep(3); 
    } 
} 

這裏是b_process.c

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

#define SHM_PATH  "/instant_messaging" 
#define SHM_SIZE   50 
#define SEM_PATH  "/sem_instant_messaging" //dddddddddd 

char *sendbuff; 

int main() 
{ 
    //sahred memory setting 
    //shm_unlink(SHM_PATH); 
    int shmfd; 

    shmfd = shm_open(SHM_PATH, O_CREAT | O_RDWR, S_IRWXU | S_IRWXG); 
    if (shmfd < 0) { 
     perror("In shm_open()"); 
     exit(1); 
    } 

    int shm_size = SHM_SIZE; 

    ftruncate(shmfd,shm_size); 
    sendbuff = (char*) mmap(NULL, shm_size, PROT_READ | PROT_WRITE, 
      MAP_SHARED, shmfd, 0); 
    if (sendbuff == NULL) { 
     perror("In mmap()"); 
     exit(1); 
    } 

    //semaphore setting 
    sem_unlink(SEM_PATH); 

    sem_t *sem1; 

    sem1 = sem_open(SEM_PATH, O_CREAT, S_IRUSR | S_IWUSR, 1); 

    while (1) { 
     printf("before wait %d\n", *sem1); 
     int status = sem_wait(sem1); 

     if (status != 0) 
     { 
      perror("in sem_wait"); 
     } 
     printf("after wait %d\n", *sem1); 
     printf("%s", sendbuff); 
     scanf("%s", sendbuff); 
     sem_post(sem1); 
    } 
} 

我已經花了很多的時間調試這和閱讀手冊頁,但它看來,雖然共享內存的工作原理和信號後,等待在每個進程的地址空間內工作,這兩個進程不會影響另一個在共享內存區域中看到的數據。

有沒有人看到我失蹤?

+0

它對我來說看起來不錯,你爲什麼說它不影響其他過程中的價值? –

+0

是的......這樣的東西最好在它所沒有的系統/環境中進行測試和調試。 OP,那將是你的。 –

+0

@先生,當我打sem_wait(sem1);它應該阻止另一個進程,但它並沒有,儘管* sem1的值從1遞減到0 – mohammed

回答

0

您的代碼中有幾件事情是可疑的,但是一件事情的組合突出顯然是錯誤的:這兩個進程在信號量路徑上執行sem_unlink(),然後立即執行sem_open()。只有當你非常幸運時,這可以產生兩個使用相同信號量的過程的效果,這樣兩個sem_unlink() s在執行sem_open()之前執行。否則,無論哪個進程第二次都將取消第一個創建的信號量的鏈接,而是創建並使用它自己的信號量。兩個過程都會繼續進行,每個過程都使用自己的獨立信號量。

我也發現它有點可疑,都處理ftruncate()共享內存區域,特別是他們在同步之前這樣做(或者如果過程有效同步的話會這樣做)。我認爲你應該讓一個進程負責設置共享內存段;另一個只需打開並映射它。糾正你的信號量初始化,並使用信號量來確保共享內存的大小,然後程序繼續使用它。

+0

是的你是對的我刪除'sem_unlink',我用'fstat'將共享內存的大小傳遞給其他進程(而不是ftruncate()),它現在正在工作,但它有一些隨機的行爲有時我不' t知道爲什麼 – mohammed

+0

很難猜測「隨機行爲」可能是什麼,但也許它與'b_process.c'中的這個錯誤代碼有關:printf(「wait%d \ n」,* sem1)'之前。沒有理由認爲一個'sem_t'對象可以被成功解釋爲一個'int',這個代碼(以及後面的類似代碼)會假設這個。如果你想打印信號量的值,那麼你可以通過'sem_getvalue()'來檢索它。 –

+0

我使用了'sem_getvalue',雖然它似乎沒有問題,但是當我簡單地在'sem_post()'之後放置了一個'sleep(1)'語句時,問題就消失了似乎它給了其他進程時間來反應在第一個進程再次循環之前加入信號量,第二次加入sem_wait()。這是正確的先生嗎? – mohammed