2017-07-14 188 views
2

我正在寫一個C程序,我正在向n個玩家發牌,由n個分叉過程表示。我希望他們都共用同一副牌,所以我試圖使用mmap()來跟蹤牌組大小,但是我必須編譯該程序的機器不允許MAP_ANONYMOUSMAP_ANON。是否還有另一種方法可以將共享內存中的全局變量存儲到C89/pre Linux 2.4中?C中的共享內存和MAP_ANONYMOUS缺失?

我的上下文程序:

static int *deck_size; 

int pop(int *arr, int *size, int loc) 
{ 
    int i; 
    int val = arr[loc]; 
    for(i = loc; i < (*size - 1); i++) 
    { 
     arr[i] = arr[(i+1)]; 
     arr[*size] = '\0'; 
    } 
    *size = *size-1; 
    return val; 
} 

int main(int argc, char* argv[]) 
{ 
    pid_t pid, wpid; 
    int status, index, players, rdm_card; 
    char outbuf[100]; 
    int deck[] = 
    {1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,8,8,8,8,9,9,9,9,10,10,10,10,11,11,11,11,12,12,12,12,13,13,13,13}; 

    deck_size = mmap(NULL, sizeof *deck_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); 
    *deck_size = 52; 
    /* reject an execution with no arguments */ 
    if(argv[1] == NULL) 
    { 
     write(STDERR_FILENO, "Usage: dealer <n>\n", 18); 
     exit(EXIT_FAILURE); 
    } 
    else 
    { 
     if((players = atoi(argv[1])) < 1) 
     { 
      write(STDERR_FILENO, "n cannot be less than 1\n", 24); 
      exit(EXIT_FAILURE); 
     } 
    } 

    srand (time(NULL)); 

    rdm_card = rand() % *deck_size; 

    for(index = 0; index < players; index++) 
    { 
     pid = fork(); 
     if (pid == 0) { 
      sprintf(outbuf, "random card: %d\n", pop(deck, deck_size, rdm_card)); 
      write(STDOUT_FILENO, outbuf, 17); 
      printf("size of deck %d!\n", *deck_size); 
      exit(EXIT_SUCCESS); 
     } else if (pid < 0) { 
      write(STDERR_FILENO, "fork error\n", 11); 
      exit(EXIT_FAILURE); 
     } else { 
      do { 
       wpid = waitpid(pid, &status, WUNTRACED); 
      } while (!WIFEXITED(status) && !WIFSIGNALED(status)); 
     } 
    } 
    return 0; 
} 
+2

你看'人2 shmget'?它描述了在POSIX shm –

+2

之前使用的古老的System V共享內存接口,您記得要定義'_BSD_SOURCE'或'_SVID_SOURCE'來從

+0

獲得MAP_ANONYMOUS您是否有一個特定的原因試圖在這裏使用分叉進程?除非這是項目需求(例如,對於編程任務),否則最好使用線程...... – duskwuff

回答

1

當你清楚地閱讀手冊頁MMAP(2)它明確規定,因爲Linux內核2.4是MAP_ANONYMOUS支持。

只是因爲2.4內核結合使用 MAP_ANONYMOUS與MAP_SHARED被支持的Linux 。

確保您定義_BSD_SOURCE_SVID_SOURCE得到MAP_ANONYMOUS

#define _BSD_SOURCE 
+0

謝謝!我沒有意識到我需要定義這些。另外,'#define _DEFAULT_SOURCE',是'_BSD_SOURCE'和'_SVID_SOURCE'的最新版本。 – MSDOStoevsky

+0

@MSDOStoevsky - 這裏有一個全新的兔子洞,可供下載這些宏:)我通常使用'_X_OPEN_SOURCE'或'_POSIX_SOURCE'。我發現'_X_OPEN_SOURCE'或'_POSIX_SOURCE'可以更好地使用C庫的C++編譯器。另請參閱GNU手冊中的[1.3.4功能測試宏](https://www.gnu.org/software/libc/manual/html_node/Feature-Test-Macros.html)。 Newlib與Glibc略有不同。 – jww

+0

但問題說「Linux 2.4之前」。這不代表Linux 2.2及更早的版本嗎? –