【问题标题】:Shared memory variable in cc中的共享内存变量
【发布时间】:2017-10-19 18:33:13
【问题描述】:

我正在为 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)不使用共享内存。
  • 我刚刚编译了你的代码并没有收到任何错误...只有一个关于dummy的警告...
  • \n放在末尾而不是printf格式控制字符串的开头,或者调用fflush
  • 请不要完全围绕您的问题范围进行编辑。当出现新问题时,请提出新问题。

标签: c fork shared-memory


【解决方案1】:

我将从对您的代码进行一些重构开始,这样就很清楚为什么您的评论中的 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;

现在,bank 是一个指向 struct Bank 的指针,它当前指向 bankGlobal。您需要将所有bank. 更改为bank-&gt;。使用此代码,您可以切换到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 semaphore 放在这个Bank 结构中,并使用sem_waitsem_post 保护这个事务。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-20
    • 1970-01-01
    • 2013-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多