Как и все, я пытался понять linux ОС лучше. Я реализовывал проблему синхронизации потребителя с использованием семафоров.
i) Будет m процессов производителя и n процессов потребителя.
ii) Продукт представлен со случайным числом.
iii) buffer
является общим для всех процессов-потребителей и производителей, а переменная in
- для всех процессов-производителей, а переменная out
- для всех процессов-потребителей.
iv) Все процессы остановятся, как только в терминал будет введен CTRL
+ C
.
Вот коды:
1.shared.h
//assume all required headers included
#define buffer_size 5
#define empty_id 0
#define full_id 1
#define mutex_id 2
#define no_sem 3
struct sembuf signall = {0 , 1, 0};
struct sembuf wait = {0, -1, 0};
#define W(s) semop(s, &wait, 1);
#define S(s) semop(s, &signall, 1);
int shmid;
int *buffer;
union semun
{
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *__buf;
} setvalarg[3];
int *create_shared_mem_buffer()
{
int *shmaddr;
key_t key = ftok("/home/******/**/B", 1);
shmid = shmget(key, buffer_size, IPC_CREAT|0660);
shmaddr= (int *)shmat(shmid, NULL, 0);
return shmaddr;
}
void clear_buffer()
{
int i;
for(i=0;i<buffer_size;i++)
buffer[i]=0;
}
void releaseSHM(int signum)
{
int status;
clear_buffer();
status = shmctl(shmid, IPC_RMID, NULL);
status = kill(0, SIGKILL);
exit(signum);
}
int create_semaphore_set()
{
key_t key= ftok("/home/******/**/A", 1);
int semid= semget(key, no_sem, IPC_CREAT|0600);
setvalarg[0].val=buffer_size;
semctl(semid, empty_id, SETVAL, setvalarg[0]);
setvalarg[1].val=0;
semctl(semid, full_id, SETVAL, setvalarg[1]);
setvalarg[2].val=1;
semctl(semid, mutex_id, SETVAL, setvalarg[2]);
return semid;
}
2.производитель. c
#include "shared.h"
void insert_product(int item, int *in, int *buffer)
{
*in=(*in+1)%buffer_size;
buffer[*in]=item;
printf("Producer produces item %d stored in posn %d \n",item,*in);
}
int shmid1;
int main(int argc, char *argv[])
{
int i, pid, item;
int *in;
buffer = create_shared_mem_buffer();
int semid= create_semaphore_set();
sighandler_t shandler;
shandler = signal(SIGINT, releaseSHM);
shmid1= shmget(IPC_PRIVATE, sizeof(int),IPC_CREAT | 0777);
in=(int *)shmat(shmid1, NULL, 0);
*in=0;
int m=5;
for(i=0;i<m;i++)
{
pid=fork();
if(pid==0)
{
while(1)
{
item=rand();
wait.sem_num=0;
W(semid);
wait.sem_num=2;
W(semid);
insert_product(item, in, buffer);
signall.sem_num=2;
S(semid);
signall.sem_num=1;
S(semid);
sleep(2); //sleep has been introduced to slowdown the output.
}
}
}
return 0;
}
потребитель. c
#include "shared.h"
int remove_product(int *out, int *buffer)
{
int item;
*out=(*out+1)%buffer_size;
item=buffer[*out];
buffer[*out]=0;
return item;
}
int shmid1;
int main(int argc, char *argv[])
{
int i, pid, item;
int *out;
buffer = create_shared_mem_buffer();
int semid= create_semaphore_set();
sighandler_t shandler;
shandler = signal(SIGINT, releaseSHM);
shmid1= shmget(IPC_PRIVATE, sizeof(int),IPC_CREAT | 0777);
out=(int *)shmat(shmid1, NULL, 0);
*out=-1;
clear_buffer(buffer);
int n=2;
for(i=0;i<n;i++)
{
pid=fork();
if(pid==0)
{
while(1)
{
wait.sem_num=1;
W(semid);
wait.sem_num=2;
W(semid);
item=remove_product(out, buffer);
printf("Consumer consumes the product %d \n", item);
signall.sem_num=2;
S(semid);
signall.sem_num=0;
S(semid);
sleep(2); //sleep has been introduced to slow down the output
}
}
}
return 0;
}
Выход примерно такой:
Producer produces item 1681692777 stored in posn 2
Producer produces item 1681692777 stored in posn 3
Producer produces item 1681692777 stored in posn 4
Producer produces item 1804289383 stored in posn 1
Producer produces item 1804289383 stored in posn 2
Producer produces item 1804289383 stored in posn 3
Producer produces item 1804289383 stored in posn 0
Producer produces item 1804289383 stored in posn 0
Producer produces item 1681692777 stored in posn 0
Producer produces item 1714636915 stored in posn 1
Producer produces item 1714636915 stored in posn 2
Producer produces item 1714636915 stored in posn 3
Producer produces item 846930886 stored in posn 1
Producer produces item 1714636915 stored in posn 4
Producer produces item 846930886 stored in posn 2
Producer produces item 1714636915 stored in posn 0
Producer produces item 846930886 stored in posn 3
Producer produces item 846930886 stored in posn 4
Producer produces item 846930886 stored in posn 0
Producer produces item 1681692777 stored in posn 1
Consumer consumes the product 424238335
Consumer consumes the product 424238335
Consumer consumes the product 424238335
Consumer consumes the product 424238335
Consumer consumes the product 719885386
Consumer consumes the product 719885386
Consumer consumes the product 719885386
Consumer consumes the product 719885386
Consumer consumes the product 719885386
Consumer consumes the product 1649760492
Consumer consumes the product 1649760492
Consumer consumes the product 596516649
Consumer consumes the product 1649760492
Consumer consumes the product 1649760492
Consumer consumes the product 1649760492
Consumer consumes the product 596516649
Consumer consumes the product 596516649
Consumer consumes the product 596516649
Как видите, тот же продукт производится больше чем один раз и один и тот же продукт потребляется более одного раза.
i) В чем проблема? Как ее решить?
ii) Также процессы не останавливаются при вводе CTRL
+ C
.
Я сделал все сам, и мне нужен кто-то, чтобы просмотреть это. Если вам нужна дополнительная информация, оставьте комментарий ниже.