信号、信号量、共有メモリを含む例
4976 ワード
信号、信号量、共有メモリを含む例(回転)
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#define SHMKEY1 (key_t)0x10
#define SHMKEY2 (key_t)0x15
#define SEMKEY (key_t)0x20
#define SIZ 5*BUFSIZ
#define IFLAGS (IPC_CREAT|IPC_EXCL)
#define ERR ((struct databuf*)-1)
//p1,v1
struct sembuf p1 = {0, -1, 0};
struct sembuf v1 = {0, 1, 0};
//p2,v1
struct sembuf p2 = {1, -1, 0};
struct sembuf v2 = {1, 1, 0};
//
static int shmid1, shmid2, semid;
//
struct databuf
{
int d_nread;
char d_buf[SIZ];
};
void fatal(char *mes)
{
perror(mes);
exit (1);
}
/** , shmat */
void getshm (struct databuf **p1, struct databuf **p2)
{ //
if ((shmid1=shmget(SHMKEY1, sizeof(struct databuf), 0600|IFLAGS)) < 0)
{
fatal ("shmget");
}
if ((shmid2=shmget(SHMKEY2, sizeof(struct databuf), 0600|IFLAGS)) < 0)
{
fatal ("shmget");
}
//
if ((*p1=(struct databuf*)(shmat(shmid1, 0, 0))) == ERR)
{
fatal("shmat");
}
if((*p2=(struct databuf*)(shmat(shmid2, 0, 0))) == ERR)
{
fatal("shmat");
}
}
int getsem()
{
// 2 ;
if ((semid=semget(SEMKEY, 2, 0600|IFLAGS)) < 0)
{
fatal("segmet");
}
// ,
if (semctl(semid, 0, SETVAL, 0) < 0)
{
fatal ("semctl");
}
// , ,
//
if (semctl(semid, 1, SETVAL, 1) < 0)
{
fatal ("semctl");
}
return (semid);
}
//
void myremove()
{
if (shmctl(shmid1, IPC_RMID, NULL) < 0)
{
fatal("shmctl");
}
if (shmctl(shmid2, IPC_RMID, NULL) < 0)
{
fatal("shmctl");
}
if (semctl(semid, 0, IPC_RMID, NULL) < 0)
fatal("semctl");
exit(0);
}
void reader(int semid, struct databuf *buf1, struct databuf *buf2)
{
for(;;)
{
unsigned short val= semctl(semid,0,GETVAL,null);
if(val<=0)
{
semop(semid,&v1,1);
}
else{
//
semop(semid, &p1, 1)
}
// , buf1->d_buf,
//read , 0 :
buf1->d_nread = read(0, buf1->d_buf, SIZ);
//v ,
semop(semid, &v1, 1);
//p , , , .
semop(semid, &p2, 1);
buf2->d_nread = read(0, buf2->d_buf, SIZ);
//v ,
semop(semid, &v2, 1);
}
}
void writer(int semid, struct databuf *buf1, struct databuf *buf2)
{
for(;;)
{
//p ,
semop(semid, &p1, 1);
//1
write(1, buf1->d_buf, buf1->d_nread);
//
semop(semid, &v1, 1);
//p , , , .
semop(semid, &p2, 1);
write(1, buf2->d_buf, buf2->d_nread);
semop(semid, &v2, 1);
}
}
int main()
{
int semid, pid;
struct databuf *buf1, *buf2;
semid = getsem();
getshm (&buf1, &buf2);
switch(pid=fork())
{
case -1:
fatal("fork");
break;
case 0:
writer(semid, buf1, buf2);
break;
default:
// ctrl+c myremove ,
// : , .
signal (SIGINT, myremove);
reader(semid, buf1, buf2);
break;
}
exit(0);
}