2013-05-26 35 views
0

我正試圖編寫一個程序,其中主進程分配共享內存,然後分叉4次。每個進程然後增加1個共享內存中的整數變量500次。所以整數變量最終保存2500.在訪問共享內存之前,進程鎖定一個信號量,並在寫入共享內存之後,該進程將其解鎖。但是程序給了我以下結果。我錯誤地使用了未命名的信號變量嗎?

[email protected]:~/thread$ ./a.out 
shared memory value : 500 by 28488 process 
shared memory value : 1000 by 28487 process 
shared memory value : 2179 by 28490 process 
shared memory value : 1500 by 28489 process 
shared memory value : 2500 by 28491 process 
[email protected]:~/thread$ ./a.out 
shared memory value : 500 by 28493 process 
shared memory value : 1000 by 28492 process 
shared memory value : 2500 by 28495 process 
shared memory value : 1500 by 28494 process 
shared memory value : 2000 by 28496 process 
[email protected]:~/thread$ ./a.out 
shared memory value : 500 by 28498 process 
shared memory value : 1000 by 28497 process 
shared memory value : 1500 by 28501 process 
shared memory value : 2000 by 28499 process 
shared memory value : 2500 by 28500 process 

第一個結果顯示奇怪的值2179.我也認爲中間結果應該是有序的,因爲一次只能有一個進程訪問共享內存。但第二個結果顯示500,1000,2500,1500,2000,這是亂序結果。

這裏是代碼片段。

#include <stdio.h> 
#include <stdlib.h> 
#include <limits.h> 
#include <unistd.h> 
#include <semaphore.h> 
#include <sys/ipc.h> 
#include <sys/shm.h> 
#include <string.h> 

#define KEY_NUM 9527 
#define MEM_SIZE 4096 

int main(int argc, char *argv[]) 
{ 
    char  buffer[1024]; 
    char  *c; 
    int   i, n, status; 
    pid_t  childpid = 0; 
    sem_t  my_lock; 
    int   counter = 0; 
    int   shm_id; 
    void  *shm_addr; 

    if((shm_id = shmget(IPC_PRIVATE, MEM_SIZE, IPC_CREAT | 0666)) == -1) 
    { 
     printf("fail to allocate a shared memory.\n"); 
     return -1; 
    } 

    shm_addr = shmat(shm_id, (void*)0, 0); 

    *(int*)shm_addr = 0; // initially 0. 

    if(sem_init(&my_lock, 1, 1) == -1) 
    { 
     perror("Could not initialize mylock semaphore"); 
     exit(1); 
    } 

    for(i = 0; i < 4; i++) 
     if(0 == fork()) 
      break;  // child process exit for-loop. 

    // entry section 
    if(sem_wait(&my_lock) == -1) 
    { 
     perror("Semaphore invalid"); 
     exit(1); 
    } 
    // start of critical section. 

    for(i = 0 ; i < 500; i++) 
    { 
     *(int*)shm_addr = *(int*)shm_addr + 1; 
    } 
    sprintf(buffer, "shared memory value : %d by %ld process\n", *(int*)shm_addr, (long)getpid()); 
    write(STDOUT_FILENO, buffer, strlen(buffer)); 
    // end of critical section. 

    // exit section 
    if (sem_post(&my_lock) == -1) 
    { 
     perror("Semaphore done"); 
     exit(1); 
    } 

    // remainder section 
    if(childpid > 0) 
    { 
     for(i = 0 ; i < n ; i++) // wait for all children. 
      wait(&status); 
     shmctl(shm_id, IPC_RMID, 0); // deallocate the shared memory. 
    } 
    exit(0); 
} 

我沒有找到問題所在。我該怎麼辦?先謝謝你。

回答

0

所創建的信號量不處於共享存儲器,所以fork後每個進程具有它的單獨的副本。您需要將計數器和信號量保存在共享內存中,請使用struct

0

首先你在你的代碼中使用了未命名的信號量。

未命名信號可以連續工作兩件事情

  1. 一個進程的線程之間。

  2. 之間的相關過程。

您在代碼中使用了相關流程。

您的代碼中的問題是,您不會共享您的信號量變量。

即讓有一個過程名爲A它有count變量,那麼你可以使用fork()。所以現在有兩個進程,父進程是A,而子進程是讓B,記得fork()後進程A和B都有自己的計數變量副本。因此,如果過程中產生改變的計數變量則變化不會反映在這個過程B.

所以如果你想通過進程A所做的改變也反映了進程B,那麼你必須的股數變量。

相關問題