Ergänzend zum Betriebssysteme Tutorial einige interessante Beispiele zur Interprozesskommunkation.
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
//SENDER PROCESS
//
//first start sender
//function open waits until receiver process has been started
#define MAX 100
void main ()
{
int fd;
char buf[MAX];
printf("Creating Pipe... Waiting for receiver process...\n\n");
//TRY TO CRATE A NAMED PIPE
if (mkfifo("FIFO_PIPE",0666)<0)
{
perror("FIFO (named pipe) could not be created.");
exit(-1);
}
else printf("\nPipe has been created...");
//OPEN PIPE
if ((fd = open ("FIFO_PIPE", O_WRONLY))<0)
{
perror("Could not open named pipe.");
exit(-1);
}
else printf("Pipe has been opened.");
//WRITE TO PIPE
strcpy(buf,"Named Pipe experiment.");
if( write (fd,buf, strlen(buf)+1) < 0 )
{
perror("Error writing to named Pipe (FIFO)");
exit(-1);
}
else printf("Message has been written to pipe.");
//CLOSE FIFO
if (close(fd)<0)
{
perror("Error closing FIFO");
exit(-1);
}
exit(0);
}
Source Code: pipe creator process
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#define MAX 100
void main ()
{
int fd;
char buf[MAX];
//OPEN PIPE WITH READ ONLY
if ((fd = open ("FIFO_PIPE", O_RDONLY))<0)
{
perror("Could not open named pipe for reading.");
exit(-1);
}
printf("Pipe has been opened. Trying to read from...\n\n");
//READ FROM PIPE
if (read( fd,buf,MAX) < 0 )
{
perror("Error reading pipe.");
exit(-1);
}
printf("\nMessage I got from pipe - %s\n",buf);
if (close(fd)<0)
{
perror("Error closing FIFO.");
exit(-1);
}
sleep(3);
if (unlink("FIFO_PIPE")<0)
{
perror("Error deleting pipe file.");
exit(-1);
}
exit(0);
}
Source Code: Pipe Receiver
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define SHMKEY 5L
#define SHMSIZE 500
//EXAMPE PROGRAMM THAT ILLUSTRATES THE USE
//OF SHARED MEMORY
//
//USAGE: process1 MESSAGE_TO_SHM
// Writes a message string into a shared memory
//
// process2
// Reads the message from the Shared Memory
void main (int argc, char *argv[])
{
int shm_ID=0;
void *pointer=NULL;
if (argc<2)
{
printf("Usage: ./processX textmessage\n\n");
exit(-1);
}
if ((shm_ID = shmget( SHMKEY,SHMSIZE,IPC_CREAT | 0666 )) < 0 )
{
perror("Error creating SHM segment.");
exit(-1);
}
else printf("\nSHM segment has been created.\n");
if ((pointer=shmat(shm_ID,NULL,0))==NULL)
{
perror("Error including SHM adress space.");
exit(0);
}
else printf("Allocating SHM to my adress space.\n");
printf("Copying message into shared memory...\n");
memcpy( pointer, argv[1], strlen(argv[1])+1);
if (shmdt(pointer)<0)
{
perror("Error deallocating shared memory.");
exit(-1);
}
else printf("SHM has been deallovated.\n");
exit(0);
}
Source Code: Process A
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define SHMKEY 5L
#define SHMSIZE 500
void main ()
{
int shm_ID=0;
void *pointer=NULL;
if ((shm_ID = shmget( SHMKEY,SHMSIZE, 0444 )) < 0 )
{
perror("Error getting SHM segment.");
exit(-1);
}
else printf("\nSHM segment has been found.\n");
if ((pointer=shmat(shm_ID,NULL,0))==NULL)
{
perror("Error including SHM adress space.");
exit(0);
}
else printf("Allocating SHM to my adress space.\n");
printf("Fetching message from shared memory:\n");
printf("\n%s\n",(char*) pointer);
if (shmdt(pointer)<0)
{
perror("Error deallocating shared memory.");
exit(-1);
}
else printf("SHM has been deallovated.\n");
exit(0);
}
Source Code: Process B
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#define SEMKEY 5L
//EXAMPLE OF SEMAPHORES
//the two processes try to write in a buffer file
//synchronisation with semaphores
//the started process1 will wait for 10 seconds in cs
//Because of semaphore the second process will have to wait
//that 10 seconds too!
void sleep(int delay)
{
time_t starttime = time(0);
long endtime = starttime+delay;
while (endtime>time(0));
}
main ()
{
union semun
{
int val;
struct semid_ds *buf;
ushort *array;
} arg;
struct sembuf ops[1];
int semid;
FILE *fp;
time_t start_time = time (0);
printf("Semaphore Process 1 has been started.\n\n");
//Get Semaphores from OS
if ((semid=semget(SEMKEY,1,0666 | IPC_CREAT))<0)
{
perror("Error getting semaphore from system.");
exit(-1);
}
//initialize semaphore
arg.val=1;
if (semctl(semid,0,SETVAL,arg)<0)
{
perror("Error initializing semaphore with semctl.");
exit(-1);
}
ops[0].sem_num = 0;
ops[0].sem_flg = 0;
ops[0].sem_op = -1; //prepare P(sem) operation
//enter critical section
if (semop(semid,ops,1)<0)
{
perror("Error running p(sem) on semaphore in process 1.");
exit(-1);
}
printf("Entering critical section of process 1 at %d\n",
time(0)-start_time);
fp=fopen("buffer","w");
fprintf(fp,"Semaphor Process 1 was here at %d\n",time(0));
sleep(10);
fclose(fp);
ops[0].sem_op=+1; //prepare V(sem) operation
if(semop(semid,ops,1)<0)
{
perror("Error running v(sem) on semaphore in process 1.");
exit(-1);
}
printf("Process 1 has been left critical section: %d\n",
time(0)-start_time);
exit(0);
}
Source Code: Process A
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#define SEMKEY 5L
void sleep(int delay)
{
time_t starttime = time(0);
long endtime = starttime + delay;
while(endtime>time(0));
}
main ()
{
union semun
{
int val;
struct semid_ds *buf;
ushort *array;
} arg;
struct sembuf ops[1];
int semid;
FILE *fp;
time_t start_time = time (0);
printf("Semaphore Process 2 has been started.\n\n");
//Get Semaphores from OS
if ((semid=semget(SEMKEY,1,0666 | IPC_CREAT))<0)
{
perror("Error getting semaphore from system.");
exit(-1);
}
//initialize semaphore not neccessary because already done
//in process 1
ops[0].sem_num = 0;
ops[0].sem_flg = 0;
ops[0].sem_op = -1; //prepare P(sem) operation
//enter critical section
if (semop(semid,ops,1)<0)
{
perror("Error running p(sem) on semaphore in process 2.");
exit(-1);
}
printf("Entering critical section of process 2 at %d\n",
time(0)-start_time);
fp=fopen("buffer","a");
fprintf(fp,"Semaphor Process 2 was here at %d\n",time(0));
sleep(3);
fclose(fp);
ops[0].sem_op=+1; //prepare V(sem) operation
if(semop(semid,ops,1)<0)
{
perror("Error running v(sem) on semaphore in process 1.");
exit(-1);
}
printf("Process 2 has been left critical section: %d\n",
time(0)-start_time);
//DELETE SEMAPHORE
if(semctl(semid,0,IPC_RMID,arg)<0)
{
perror("Could not delete semaphore.");
exit(-1);
}
exit(0);
}
Source Code: Process B
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define MAXLEN 256
#define MSGKEY 5L
//EXAMPLE for unix message queues to communicate
//message will be stored in OS managed queue
//if message queue is empty, the receiver will wait
//until the sender will have send a message
struct my_msgbuf
{
long mtype;
char message[MAXLEN];
};
void main (int argc, char *argv[])
{
my_msgbuf buffer;
int msgID;
if (argc<2)
{
printf("Give message as parameter!");
exit(-1);
}
//create and get a message queue
if ((msgID=msgget(MSGKEY,0666|IPC_CREAT))<0)
{
perror("Error getting msg queue.");
exit(-1);
}
//copy the message into the buffer (prepare)
strcpy(buffer.message,argv[1]);
buffer.mtype=1L; //TYPEDEF MESSAGE TO 1
//send the message to the OS-managed buffer
if (msgsnd(msgID,(struct msgbuf*)&buffer,sizeof(buffer.message),0)<0)
{
perror("Error writing to message queue.");
exit(-1);
}
printf("Message has been send.\n\n");
exit(0);
}
Source Code: Message Sender Process
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define MAXLEN 256
#define MSGKEY 5L
struct my_msgbuf
{
long mtype;
char message[MAXLEN];
};
void main ()
{
my_msgbuf buffer;
int msgID;
//create and get a message queue
if ((msgID=msgget(MSGKEY,0666|IPC_CREAT))<0)
{
perror("Error getting msg queue.");
exit(-1);
}
//RECEIVE MESSAGE FROM OPERATING SYSTEMS QUEUE
if (msgrcv(msgID,(struct msgbuf*)&buffer,
sizeof(buffer.message),0L,0)<0)
{
perror("Error receiving message from Queue.");
exit(-1);
}
printf("\nMessage read from queue:\n\n");
printf("MESSAGE: %s\n",buffer.message);
printf("TYPE:%ld\n",buffer.mtype);
//DELETE QUEUE
if (msgctl(msgID,IPC_RMID,0)<0)
{
perror("Error deleting message queue.");
exit(-1);
}
exit(0);
}
Source Code: Message Receiver Process