我正在尝试将变量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;
}
答案 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);
}