问题:
所以在我的实现中我使用三个信号量:all(作为屏障)= 1,new = 0和mutex = 1。我也使用共享计数器= 0来计算有多少消费者已经阅读了元素。
代码:
#include <time.h>
#include <sys/shm.h>
#include "stdio.h"
#include "sys/sem.h"
#include "stdlib.h"
#include "unistd.h"
int sem_id;
int shmid;
typedef struct sharedMemory{
int value;
}sharedMemory;
union semun {
int val;
struct semid_ds * buf;
unsigned short * array;
};
#define M 4
#define N 2
typedef enum semIndex{
mutex= 0,
all=1,
new=2
}semIndex;
int sem_init(semIndex index,int val){
union semun sem_union;
sem_union.val = val;
if (semctl(sem_id, index, SETVAL, sem_union) == -1) return 0;
return 1;
}
int up(semIndex index) {
struct sembuf sem_b;
sem_b.sem_num = index;
sem_b.sem_op = 1;
if (semop(sem_id, &sem_b, 1) == -1) {
perror("Failed to up");
return 0;
}
return 1;
}
int down(semIndex index) {
struct sembuf sem_b;
sem_b.sem_num = index;
sem_b.sem_op = -1;
if (semop(sem_id, &sem_b, 1) == -1) {
perror("Failed to up");
return 0;
}
return 1;
}
void *getShMemory(int memory) {
shmid = shmget((key_t)1234+memory, sizeof(sharedMemory), 0666 | IPC_CREAT);
if (shmid == -1) {
fprintf(stderr, "shmget failed\n");
exit(EXIT_FAILURE);
}
void* shared_memory = shmat(shmid, (void *)0, 0);
if (shared_memory == (void *)-1) {
fprintf(stderr, "shmat failed\n");
exit(EXIT_FAILURE);
}
return shared_memory;
}
int main(void){
srand(getpid() + rand()%500);
int *array = malloc(M * sizeof(int));
for (int i = 0; i < M; ++i) {
array[i] = rand() % 20;
}
sem_id = semget(6846, 3, 0666 | IPC_CREAT);
sharedMemory *sharedMem = (sharedMemory*) getShMemory(2);
sem_init(all,1);
sem_init(mutex,1);
sem_init(new,0);
pid_t pid = fork();
if (pid>0){
for (int i = 0; i < M; ++i) {
down(all);
down(mutex);
sharedMem->value = array[i];
up(mutex);
up(new);
}
for (int j = 0; j < M; ++j) {
printf("%d,",array[j]);
}
putchar('\n');
}
else{
sem_id = semget(6846, 3, 0666 | IPC_CREAT);
int *array = malloc(M*sizeof(int));
sharedMemory* consumerMem = (sharedMemory*)getShMemory(1);
down(new);
consumerMem->value = 0;
for(int i=0;i<N;++i){
if(fork() == 0) {
for (int j = 0; j < M; ++j) {
down(mutex);
consumerMem = (sharedMemory*)getShMemory(1);
sharedMemory *sharedMem = (sharedMemory*) getShMemory(2);
array[j] = sharedMem->value;
consumerMem->value++;
up(mutex);
if (consumerMem->value == N) {
down(mutex);
consumerMem->value = 0;
up(mutex);
up(all); //signal producer to create new element
}
down(new); //wait for new element
up(new); //unblock one more consumer
}
for (int j = 0; j < M; ++j) {
printf("%d,",array[j]);
}
putchar('\n');
exit(0);
}
}
}
}
有时它按预期工作,所以它应该是竞争条件,但我无法指出它。任何线索?
更新的 我设法与Clion一起运行调试。我无法用调试器复制问题,因此更难确定问题。