如何在共享内存中存储变量

时间:2017-10-26 18:49:04

标签: c fork shared-memory

我正在尝试将变量bank添加到共享内存中,以使用信号量探索竞争条件和进程同步。当我在共享内存中设置变量时,我的程序给了我分段错误:11。有人可以解释我在这里做错了什么以及如何解决这个问题?谢谢!

RACE

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

    int shmid;
    int shmkey = 585858;
    sem_t mutex; // semaphore global variable

    struct Bank {
        int balance[2];
    };

    struct Bank *bank;

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

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

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

        int i;
        void* voidptr = NULL;

        // initialize semaphore
        sem_init(&mutex, 0, 1);

        // shared memory
        //bank = mmap(NULL, sizeof(struct Bank), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
        // create shared memory 
       shmid = shmget(shmkey, 1024, IPC_CREAT);
       // attach to shared memory
       bank = shmat(shmid, NULL, 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;
        }
        sem_destroy(&mutex);
        // deattach shared memory pointer
        shmdt(&bank,NULL);
        //munmap(bank, sizeof(struct Bank));
        return 0; 
    }

1 个答案:

答案 0 :(得分:0)

好吧,它给你一个段错误的原因是因为你可能以非特权用户的身份运行这个程序。 shmat需要特权。如果你在linux下运行它,你可以这样做:

  

sudo setcap cap_ipc_owner = ep ./myprog

使其能够拨打shmat等。

然后运行它。

如果你添加了一些错误处理,你会发现这个:

   shmid = shmget(shmkey, 1024, IPC_CREAT);
   if (shmid == -1 ) {
       perror("shmget");
       exit(errno);
   }
   // attach to shared memory
   bank = shmat(shmid, NULL, 0);

   if (bank == (void *)-1) {
       perror("bank");
       exit(errno);
   }