这是生产者 - 消费者问题的简单(几乎)解决方案。 它使用等待和信号功能,但可能会阻止其中一个等待。
以下是我的文件: prod.c
int *pam;
#define MAX 10
#define MAX2 12
#define PUSTY 2 //EMPTY
#define S1 0
#define PELNY 1 //FULL
#define zapis pam[MAX+1] //write
#define odczyt pam[MAX] //read
int main() {
int i;
time_t czas;
key_t klucz, kluczm;
int semID;
int shmID;
int N=3;
printf("producer--------------------------------\n");
if((klucz=ftok(".", 'A')) == -1)
{printf("Blad ftok (A)\n"); exit(2);};
semID=alokujSem(klucz, N, IPC_CREAT | 0666);
if(semID==-1)
{printf("blad semafora - producent\n");exit(1);}
kluczm=ftok(".", 'B');
shmID=shmget(kluczm, MAX2*sizeof(int), IPC_CREAT | 0666);
if(shmID==-1)
{printf("blad pamieci dzielonej - producent\n");exit(1);}
pam=(int*)shmat(shmID, NULL, 0);
time(&czas);
i=((int)czas)%100;
waitSemafor(semID, PUSTY, 0);
waitSemafor(semID, S1, 0);
pam[zapis]=i;
zapis=(zapis+1)%MAX;
printf("Wyprodukowano: %d\n", pam[zapis]);
signalSemafor(semID, S1);
signalSemafor(semID, PELNY);
printf("Po signal - producent\n");
}
kons.c
int *pam;
#define MAX 10
#define MAX2 12
#define PUSTY 2 //EMPTY
#define S1 0
#define PELNY 1 //FULL
#define zapis pam[MAX+1] //write
#define odczyt pam[MAX] //read
int main()
{
key_t klucz, kluczm;
int semID, shmID;
int i;
int N =3;
printf("consumer------------------------------------\n");
if( (klucz=ftok(".", 'A')) == -1)
{
printf("BLad frok(A)\n");
exit(2);
}
semID=alokujSem(klucz, N, IPC_CREAT | 0666);//allocate semaphores
if(semID==-1)
{printf("blad semafora-konsument\n"); exit(1);};
klucz = ftok(".", 'B');
shmID = shmget(kluczm, MAX2*sizeof(int), IPC_CREAT|0666);//adding to shared memory
if(shmID==-1)
{printf("blad pamieci dzielonej-konsument\n");exit(1);};
pam=(int*)shmat(shmID, NULL, 0);
waitSemafor(semID, PELNY, 0);
waitSemafor(semID, S1, 0);
printf("konsumuje %d \n",pam[odczyt]);
odczyt=(odczyt+1)%MAX;
signalSemafor(semID, S1);
signalSemafor(semID, PUSTY);
printf("Konsument skonczyl\n");
}
operacje.c
int alokujSem(key_t klucz, int number, int flagi) {
int semID;
if((semID=semget(klucz, number, flagi)) == -1)
{perror("Blad semget (alokujsemafor): "); exit(1); }
return semID;
}
int zwolnijSem(int semID, int number) {
return semctl(semID, number, IPC_RMID, NULL);
}
void inicjalizujSem(int semID, int number, int val) {
if(semctl(semID, number, SETVAL, val) == -1)
{perror("Blad semctl (inicjalizujsemafor): "); exit(1);}
}
int waitSemafor(int semID, int number, int flags)
{
printf("Wszedłem do wait z numerem %d", number);
struct sembuf operacje[1];
operacje[0].sem_num = number;
operacje[0].sem_op = -1;
operacje[0].sem_flg = SEM_UNDO;
if ( semop(semID, operacje, 1) == -1 )
{
printf("Semop error: %s\n", strerror(errno));
perror("Blad semop (waitSemafor)");
return -1;
}
return 1;
}
void signalSemafor(int semID, int number)
{
struct sembuf operacje[1];
operacje[0].sem_num = number;
operacje[0].sem_op = 1;
operacje[0].sem_flg = SEM_UNDO;
if (semop(semID, operacje, 1) == -1 )
perror("Blad semop (postSemafor): ");
}
我不知道为什么,但它甚至没有从waitSemafor()打印printf(“...”)。
和mainp.c
#define P 2 // processes amount
#define MAX 10
#define MAX2 12
#define PUSTY 2 //EMPTY
#define S1 0
#define PELNY 1 //FULL
int main() {
key_t klucz, kluczm;
int semID;
int shmID;
int i;
int N=3;
if ( (klucz = ftok(".", 'A')) == -1 )
{
printf("Blad ftok (main)\n");
exit(1);
}
semID=alokujSem(klucz, N, IPC_CREAT | IPC_EXCL | 0666);
inicjalizujSem(semID, S1, 1);
inicjalizujSem(semID, PELNY, 0);
inicjalizujSem(semID, PUSTY, MAX);
printf("Semaphore ready!\n");
kluczm=ftok(".",'B');
shmID=shmget(kluczm, MAX2*sizeof(int), IPC_CREAT|IPC_EXCL|0666);
for(i=0; i< P; i++)
switch(fork())
{
case -1:
perror("Blad fork(mainprog)");
exit(2);
case 0:
execl("./prod", "prod", NULL);
}
for(i=0; i<P; i++)
switch(fork())
{
case -1:
printf("Blad fork (mainprog)\n");
exit(2);
case 0:
execl("./kons", "kons", NULL);
}
for(i=0; i<2*P;i++) {
wait(NULL);
}
zwolnijSem(semID,N); //release semaphore
shmctl(shmID,IPC_RMID, NULL);
printf("MAIN: Koniec.\n");
}
打印到控制台的唯一因素是:
信号量准备好了! 消费者 - - - - - - - - - - - - - - - - - - 消费者 - - - - - - - - - - - - - - - - - - 制片人-------------------------------- 生产者--------------------------------
它挂在那里。订单也很奇怪,生产者应该是第一位。
我使用gcc编译它,它看起来像这样:
- gcc -c -o operacje operacje.c
- gcc -o kons kons.c operacje
- gcc -o prod prod.c operacje
- gcc -o mainp mainp.c operacje
- 然后运行“./mainp”
我将非常感谢任何想法或解决方案。