|

楼主 |
发表于 2007-3-3 17:26:03
|
显示全部楼层
#define N 10 /* number of loops */
typedef int semaphore; /* semapthores are a special kind of int */
struct producer_consumer
{
semaphore mutex; /* controls access to critical region */
semaphore empty; /* counts empty buffer slots */
semaphore full; /* counts full buffer slots */
};
void display(char *str)
{
char *tmp;
for (tmp = str; *tmp; tmp++)
{
write(1, tmp, 1);
usleep(100);
}
}
int main(int argc, char *argv[])
{
int i;
int shmid;
struct producer_consumer *pc;
struct sembuf up = {0, 1, 0};
struct sembuf down = {0, -1, 0};
int pid;
pc = (struct producer_consumer *)malloc(sizeof(struct producer_consumer));
if (pc == NULL)
{
fprintf(stderr, "unable to malloc memory\n");
return -1;
}
shmid = shmget(IPC_PRIVATE, sizeof(struct producer_consumer), 0600);
if (shmid < 0)
{
perror("shmget error\n");
exit(1);
}
pc = (struct producer_consumer *)shmat(shmid, 0, 0);
if ((pc->mutex = semget(IPC_PRIVATE, 1, 0600)) < 0)
{
perror("semget mutex error\n");
exit(1);
}
if ((pc->empty = semget(IPC_PRIVATE, 1, 0600)) < 0)
{
perror("semget empty error\n");
exit(1);
}
if ((pc->full = semget(IPC_PRIVATE, 1, 0600)) < 0)
{
perror("semget full error\n");
exit(1);
}
if (semop(pc->mutex, &up, 1) < 0)
{
perror("semop mutex\n");
exit(1);
}
if (semop(pc->empty, &up, 1) < 0)
{
perror("semop empty\n");
exit(1);
}
pid = fork();
if (pid < 0)
{
perror("fork");
exit(-1);
}
if (pid > 0)
{
/**
* Parent Process
*/
for (i=0; i<N; i++)
{
if (semop(pc->empty, &down, 1) < 0)
{
perror("semop empty\n");
exit(1);
}
if (semop(pc->mutex, &down, 1) < 0)
{
perror("semop mutex\n");
exit(1);
}
display("ab");
if (semop(pc->mutex, &up, 1) < 0)
{
perror("semop mutex\n");
exit(1);
}
if (semop(pc->full, &up, 1) < 0)
{
perror("semop full\n");
exit(1);
}
}
wait(NULL);
if (semctl(pc->mutex, 0, IPC_RMID) < 0)
{
perror("remove mutex\n");
exit(1);
}
if (semctl(pc->empty, 0, IPC_RMID) < 0)
{
perror("remove empty\n");
exit(1);
}
if (semctl(pc->full, 0, IPC_RMID) < 0)
{
perror("remove full\n");
exit(1);
}
if (shmdt((void*)pc) < 0)
{
perror("unable to detach shared variable\n");
exit(1);
}
if (shmctl(shmid, IPC_RMID, 0) < 0)
{
perror("unable to destroy shared variable\n");
exit(1);
}
// free(pc);
}
else
{
/**
* Child Process
*/
for (i=0; i<N; i++)
{
if (semop(pc->full, &down, 1) < 0)
{
perror("semop full\n");
exit(1);
}
if (semop(pc->mutex, &down, 1) < 0)
{
perror("semop mutex\n");
exit(1);
}
display("cd\n");
if (semop(pc->mutex, &up, 1) < 0)
{
perror("semop mutex\n");
exit(1);
}
if (semop(pc->empty, &up, 1) < 0)
{
perror("semop empty\n");
exit(1);
}
}
if (shmdt((void*)pc) < 0)
{
perror("unable to detach shared variable\n");
exit(1);
}
}
return 0;
} |
|