模拟生产者-消费者的示例程序:
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#define MY_SHMKEY 10071500 // need to change
#define MY_SEMKEY 10071500 // need to change
void sigend(int);
int shmid, semid;
int main(void)
{
int *shmptr, semval, local;
struct sembuf semopbuf;
if((shmid=shmget(MY_SHMKEY, sizeof(int), IPC_CREAT|IPC_EXCL|0666)) < 0)
{ /* shared memory exists, act as client */
shmid=shmget(MY_SHMKEY, sizeof(int), 0666);
semid=semget(MY_SEMKEY, 2, 0666);
shmptr=(int *)shmat(shmid, 0, 0);
printf("Act as producer. To end, input 0 when prompted.\n\n");
printf("Input a number:\n");
scanf("%d", &local);
while( local )
{
semopbuf.sem_num=0;
semopbuf.sem_op=-1;
semopbuf.sem_flg=SEM_UNDO;
semop(semid, &semopbuf, 1); /* P(S1) */
*shmptr = local;
semopbuf.sem_num=1;
semopbuf.sem_op=1;
semopbuf.sem_flg=SEM_UNDO;
semop(semid, &semopbuf, 1); /* V(S2) */
printf("Input a number:\n");
scanf("%d", &local);
}
}
else /* acts as server */
{
semid=semget(MY_SEMKEY, 2, IPC_CREAT|0666);
shmptr=(int *)shmat(shmid, 0, 0);
semval=1;
semctl(semid, 0, SETVAL, semval); /* set S1=1 */
semval=0;
semctl(semid, 1, SETVAL, semval); /* set S2=0 */
signal(SIGINT, sigend);
signal(SIGTERM, sigend);
printf("ACT CONSUMER!!! To end, try Ctrl+C or use kill.\n\n");
while(1)
{
semopbuf.sem_num=1;
semopbuf.sem_op=-1;
semopbuf.sem_flg=SEM_UNDO;
semop(semid, &semopbuf, 1); /* P(S2) */
printf("Shared memory set to %d\n", *shmptr);
semopbuf.sem_num=0;
semopbuf.sem_op=1;
semopbuf.sem_flg=SEM_UNDO;
semop(semid, &semopbuf, 1); /* V(S1) */
}
}
}
void sigend(int sig)
{
shmctl(shmid, IPC_RMID, 0);
semctl(semid, IPC_RMID, 0);
exit(0);
}
模拟临界资源访问的示例程序:
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define MY_SHMKEY 10071800 // need to change
#define MAX_BLOCK 1024
#define MAX_CMD 8
struct shmbuf {
int top;
int stack[MAX_BLOCK];
} *shmptr, local;
char cmdbuf[MAX_CMD];
int shmid, semid;
void sigend(int);
void relblock(void);
int getblock(void);
void showhelp(void);
void showlist(void);
void getcmdline(void);
int main(void)
{
if((shmid=shmget(MY_SHMKEY, sizeof(struct shmbuf), IPC_CREAT|IPC_EXCL|0666)) < 0)
{ /* shared memory exists, act as client */
shmid=shmget(MY_SHMKEY, sizeof(struct shmbuf), 0666);
shmptr=(struct shmbuf *)shmat(shmid, 0, 0);
local.top=-1;
showhelp();
getcmdline();
while(strcmp(cmdbuf,"end\n"))
{
if(!strcmp(cmdbuf,"get\n"))
getblock();
else if(!strcmp(cmdbuf,"rel\n"))
relblock();
else if(!strcmp(cmdbuf,"list\n"))
showlist();
else if(!strcmp(cmdbuf,"help\n"))
showhelp();
getcmdline();
}
}
else /* acts as server */
{
int i;
shmptr=(struct shmbuf *)shmat(shmid, 0, 0);
signal(SIGINT, sigend);
signal(SIGTERM, sigend);
printf("NO OTHER OPERATION but press Ctrl+C or use kill to end.\n");
shmptr->top=MAX_BLOCK-1;
for(i=0; i<MAX_BLOCK; i++)
shmptr->stack[i]=MAX_BLOCK-i;
sleep(1000000); /* cause sleep forever. */
}
}
void sigend(int sig)
{
shmctl(shmid, IPC_RMID, 0);
semctl(semid, IPC_RMID, 0);
exit(0);
}
void relblock(void)
{
if(local.top<0)
{
printf("No block to release!");
return;
}
shmptr->top++;
shmptr->stack[shmptr->top]=local.stack[local.top--];
}
int getblock(void)
{
if(shmptr->top<0)
{
printf("No free block to get!");
return;
}
local.stack[++local.top]=shmptr->stack[shmptr->top];
shmptr->top--;
}
void showhelp(void)
{
printf("\navailable COMMAND:\n\n");
printf("help\tlist this help\n");
printf("list\tlist all gotten block number\n");
printf("get\tget a new block\n");
printf("rel\trelease the last gotten block\n");
printf("end\texit this program\n");
}
void showlist(void)
{
int i;
printf("List all gotten block number:\n");
for(i=0; i<=local.top; i++)
printf("%d\t", local.stack[i]);
}
void getcmdline(void)
{
printf("\n?> ");
fgets(cmdbuf, MAX_CMD-1, stdin);
}