[<<Previous Entry] [^^Up^^] [Next Entry>>] [Menu] [About The Guide]
Производитель и Потребитель буфера
ПРОИЗВОДИТЕЛЬ БУФЕРА, prod_onebuf.c :
/* producer program:
producer program sets up a buffer to be read by a consumer
semaphores are used to ensure that producer doesn't
overwrite an unread buffer and consumer doesn't
the same data more than once.
*/
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#define MSG_SIZE 30
#define MAX 5
main()
{
key_t key;
/* two semaphores in a set
index 0 -incremented when producer has reset buffer
-tested and decremented by consumer to check
if buffer has been reset
index 1 -incremented when consumer has read buffer
-tested and decremented by producer to check
if consumer is done
*/
static struct sembuf wait_consumed = { 1, -1, 0};
static struct sembuf signal_produced = { 0, 1, 0};
int semid, shmid, i;
char *message;
if((key = ftok( getenv("HOME"), 'u')) == -1){
fprintf(stderr,"ftok key formation error\n");
exit(1);
}
if((semid=semget(key, 2, IPC_CREAT | 0660)) == -1){
perror("producer semget():");
exit(2);
}
if((shmid=shmget(key, MSG_SIZE, IPC_CREAT | 0660)) == -1) {
perror("producer shmget():");
exit(3);
}
message=shmat(shmid, 0, 0);
for(i=1; i < MAX; i++) {
/* producer has to go first */
if(i > 1)
semop(semid,&wait_consumed,1);
sprintf(message, "message %d", i);
semop(semid, &signal_produced, 1);
}
shmdt(message);
sleep(5); /* allow consumer to digest last message */
/* alternatively a DELIMITER string could be placed in
shared memory when seen by the consumer, it would exit.
the producer would do shmctl(...,IPC_STAT,...)
and when shm_attach==1
it would remove the two IPC facilities
*/
shmctl(shmid, IPC_RMID, NULL);
semctl(semid, 0, IPC_RMID ,0);
}
NОТРЕБИТЕЛЬ БУФЕРА, cons_onebuf.c :
/* consumer program:
producer program sets up a buffer to be read by a consumer.
semaphores are used to ensure that producer doesn't
overwrite an unread buffer and consumer doesn't
read the same data more than once.
*/
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#define MSG_SIZE 30
main(int argc, char *argv[])
{
key_t key;
/* two semaphores in a set
index 0 - incremented when producer has reset buffer
- tested and decremented by consumer to check
if buffer has been reset
index 1 - incremented when consumer has read buffer
- tested and decremented by producer to check
if consumer is done
*/
static struct sembuf wait_produced = { 0, -1, 0};
static struct sembuf signal_consumed = { 1, 1, 0};
int semid, shmid, rtn;
char *message;
if((key = ftok( getenv("HOME"), 'u')) == -1){
fprintf(stderr,"ftok key formation error\n");
exit(1);
}
/* either producer or consumer might be the creator
but producer will be the remover of the IPC resources.
producer and consumer's effective uid must be the same.
*/
if ((semid=semget(key, 2, IPC_CREAT | 0660)) == -1) {
perror("consumer semget():");
exit(2);
}
if ((shmid=shmget(key, MSG_SIZE, IPC_CREAT | 0660)) == -1) {
perror("producer shmget():");
exit(3);
}
message=shmat(shmid, (char *)0, SHM_RDONLY);
while(1){
rtn=semop(semid,&wait_produced,1);
/* when producer is done semid will be IPC_RMID forcing break */
if(rtn == -1){
perror("consumer - semop on wait_consumed");
break;
}
printf("%s received: %s\n", argv[0], message);
semop(semid, &signal_consumed, 1);
}
shmdt(message);
exit(0);
}
ВЫЗОВ:
$ prod_onebuf&
14649
$ cons_onebuf
cons_onebuf received: message 1
cons_onebuf received: message 2
cons_onebuf received: message 3
cons_onebuf received: message 4
consumer-semop on wait_consumed:Identifier removed