我有一个代码,它从共享内存中读取一个整数,然后在子进程中增加这个数字。我正在使用信号量来锁定这个关键区域,以便只有在没有其他进程不增加它的情况下才会增加整数。所以我得到了一个稳定的整数值。
我为此使用了 SYSTEM V Semaphore,但是我无法使它工作,因为看起来我对这些功能的使用没有做任何事情。
该程序简单地生成 100 个进程,其中每个进程将共享内存中的整数加 1。(最初由另一个程序创建的共享内存段,如果您也需要,请告诉我!)
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/sem.h>
#include <unistd.h>
#include <sys/wait.h>
#define FIFO_PATH "/tmp/RESULT_FIFO"
#define PROC_NUM 10
#define MAX_ITERATIONS 1
#define SHM_SIZE 1024
#define SHM_KEY 23423
int shmid, *shmdata, semid;
struct sembuf semaphore;
int main() {
FILE *fp_fifo;
/* Initialize Semaphore */
semid = semget (2134L, 0, IPC_PRIVATE);
if(semid <0) {
semid = semget (2134, 1, IPC_CREAT | IPC_EXCL | 0666);
if (semid < 0) {
perror("semget()");
exit(EXIT_FAILURE);
}
}
semctl(semid, 0, SETVAL, (int)1);
shmid = shmget(234234, sizeof(int), 0777);
if(shmid == -1) {
perror("shmget()");
exit(EXIT_FAILURE);
}
shmdata = shmat(shmid, 0, 0);
if(shmdata == -1) {
perror("shmat()");
exit(EXIT_FAILURE);
}
printf("key is53 %i \n", *shmdata);
for (int i = 0; i < 100; ++i) {
int t = fork();
if(t > 0) {
/*parent*/
} else if(t == -1) {
perror("fork()");
} else if(t == 0) {
/* Child*/
semaphore.sem_op = -1;
semaphore.sem_num = 0;
semaphore.sem_flg = SEM_UNDO;
if(semop(semid, &semaphore, 1) == -1) {
perror("semop()");
exit(EXIT_FAILURE);
}
*shmdata=*shmdata+1;
semaphore.sem_op = 1;
if(semop(semid, &semaphore, 1) == -1) {
perror("semop()");
exit(EXIT_FAILURE);
}
return EXIT_SUCCESS;
}
}
wait(0);
printf("key is53 %i \n", *shmdata);
if((fp_fifo = fopen(FIFO_PATH, "w")) == NULL) {
perror("fopen");
exit(EXIT_FAILURE);
}
fprintf(fp_fifo, "%d", *shmdata);
shmdata = 0;
shmdt(shmdata);
return EXIT_SUCCESS;
}
最佳答案
我发现错误是因为 wait() 工作不正常。
信号量工作正常,但没有正确使用 wait(NULL)。这是我的一个简单示例的更正版本,如何使用 系统 V 信号量 :
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/sem.h>
#include <unistd.h>
#include <sys/wait.h>
#define FIFO_PATH "/tmp/RESULT_FIFO"
#define PROC_NUM 10
#define MAX_ITERATIONS 1
#define SHM_SIZE 1024
#define SHM_KEY 23423
int shmid, *shmdata, semid;
struct sembuf semaphore;
int main() {
FILE *fp_fifo;
/* Initialize Semaphore */
semid = semget (2134L, 0, IPC_PRIVATE);
if(semid <0) {
semid = semget (2134, 1, IPC_CREAT | IPC_EXCL | 0666);
if (semid < 0) {
perror("semget()");
exit(EXIT_FAILURE);
}
}
semctl(semid, 0, SETVAL, (int)1);
shmid = shmget(234234, sizeof(int), 0777);
if(shmid == -1) {
perror("shmget()");
exit(EXIT_FAILURE);
}
shmdata = shmat(shmid, 0, 0);
if(shmdata == -1) {
perror("shmat()");
exit(EXIT_FAILURE);
}
printf("key is46 %i \n", *shmdata);
for (int i = 0; i < 100; ++i) {
int t = fork();
if(t > 0) {
/*parent*/
wait(NULL);
} else if(t == -1) {
perror("fork()");
} else if(t == 0) {
/* Child*/
semaphore.sem_op = -1;
semaphore.sem_num = 0;
semaphore.sem_flg = SEM_UNDO;
if(semop(semid, &semaphore, 1) == -1) {
perror("semop()");
exit(EXIT_FAILURE);
}
*shmdata= *shmdata+1;
// printf("key is65 %i \n", *shmdata);
semaphore.sem_op = 1;
if(semop(semid, &semaphore, 1) == -1) {
perror("semop()");
exit(EXIT_FAILURE);
}
return EXIT_SUCCESS;
}
}
printf("key is73 %d \n", *shmdata);
if((fp_fifo = fopen(FIFO_PATH, "w")) == NULL) {
perror("fopen");
exit(EXIT_FAILURE);
}
fprintf(fp_fifo, "%d", *shmdata);
shmdata = 0;
shmdt(shmdata);
return EXIT_SUCCESS;
}
关于C 系统 v 信号量未锁定临界区,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55972398/