2017-10-19 29 views
0

私はuniの割り当てを行っていますが、共有メモリにグローバル変数Bankを定義する際に問題があり、プロセスに共有アドレスがあるようになっています。私たちは競合状態を探索しています。私は、両方のプロセスがMakeTransactions()を呼び出し、競合状態を解消するためにセマフォを利用することになっています。現在、私は共有メモリに関する異なる型(int vs struct)のエラーに陥っています。誰かがこれについて最善の方法を説明することができますか?どんな提案も役に立ちます。ありがとう!共有メモリの変数が

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

    struct Bank { 
     int balance[2]; 
    }; 

    struct Bank = *bank; 

    // routine for thread execution 
    void* MakeTransactions() { 
     int i, j, tmp1, tmp2, rint; 
     double dummy; 

     for (i=0; i < 100; i++) { 
      rint = (rand()%30)-15; 
      if (((tmp1=bank->balance[0])+rint) >=0 && 
        ((tmp2=bank->balance[1])-rint)>=0) { 
       bank->balance[0] = tmp1 + rint; 
       for (j=0; j < rint*100; j++) { 
        dummy=2.345*8.765/1.234; // spend time on purpose 
       } 
       bank->balance[1] = tmp2 - rint; 
      } 
     } 
     return NULL; 
    } 

    int main(int argc, char **argv) { 

     int i; 
     void* voidptr = NULL; 

      bank = mmap(NULL, sizeof(struct Bank), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); 
      //check if bank is not NULL 
      bank->balance[0] = 100; 
      bank->balance[1] = 100; 

     pid_t pid; 
     srand(getpid()); 

     printf("\nInit balances A:%d + B:%d ==> %d!", 
       bank->balance[0],bank->balance[1],bank->balance[0]+bank->balance[1]); 

     pid=fork(); 
     if (pid < 0) { 
      fprintf(stderr, "Fork failed"); 
      return 1; 
     } 
     if (pid == 0) { 
      printf("\nChild computing ..."); 
      MakeTransactions(); 
      printf("\nChild process complete"); 
      printf("\nLet's check the balances A:%d + B:%d ==> %d ?= 200", 
      bank->balance[0],bank->balance[1],bank->balance[0]+bank->balance[1]); 
      return 0; 
     } 
     else { 
      printf("\nParent computing...\n"); 
      MakeTransactions(); 
      wait(NULL); 
      printf("\nParent process complete\n"); 
      printf("Let's check the balances A:%d + B:%d ==> %d ?= 200\n\n", 
        bank->balance[0],bank->balance[1],bank->balance[0]+bank->balance[1]); 
      return 0; 
     } 
     return 0; 
    } 
+0

エラーメッセージが表示されますか?なぜそれを質問に追加しないでください!また、あなたのコード(mmapをコメントアウトしたもの)は共有メモリを使用しません。 –

+0

私はちょうどあなたのコードをコンパイルしましたが、エラーは発生しませんでした... 'dummy'に関する警告のみ... – rodrigo

+0

' printf'形式の制御文字列の最後に '\ n'を置くか、' fflush'を呼び出してください –

答えて

1

あなたのコードを少しリファクタリングして開始するので、あなたのコメントのmmapがうまくいかない理由は明らかです。

あなたの構造体宣言非Annonymousの作り:

struct Bank { 
    int balance[2]; 
}; 

そして、あなたの世界:struct Bank bank = {{100,100}};を。さて、このbank変数がスタックにあると、mmapへの切り替えが難しくなります。間接の紹介:

struct Bank bankGlobal = {{100, 100}}; 
struct Bank *bank = &bankGlobal; 
... 
bank->balance[0] = tmp1 + rint; 

は今、bankstruct Bankへのポインタであり、それは現在bankGlobalを指します。 bank.bank->に変更する必要があります。このコードを使用すると、mmapソリューションに切り替えることができます。

まず、グローバル変数でmmapを使用して銀行変数を初期化することはできません。それは機能している必要があります。次に、構造体サイズ全体を対象とする必要があるときに、Bank(sizeof *Bank)へのポインタのサイズを取得しようとしています。

-struct Bank bankGlobal = {{100, 100}}; 
-struct Bank *bank = &bankGlobal; 
+struct Bank *bank; 

を、main関数で:

ので、これを変更

bank = mmap(NULL, sizeof(struct Bank), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); 
//check if bank is not NULL 
bank->balance[0] = 100; 
bank->balance[1] = 100; 

完了したらと、munmapすることを忘れないでください。

レースについてはPOSIX semaphoreをこのBank構造体に入れてsem_waitsem_postでこの取引を保護することができます。