簡體   English   中英

C中的共享內存變量

[英]Shared memory variable in c

我正在為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; 
    }

我將首先對您的代碼進行一些重構,因此很明顯為什么注釋中的mmap無法正常工作。

使您的結構聲明不匿名:

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;

在主要功能上:

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信號量放入此Bank結構中,並使用sem_waitsem_post保護該事務。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM