现在的位置: 首页 > 综合 > 正文

producter-consumer

2012年03月26日 ⁄ 综合 ⁄ 共 3105字 ⁄ 字号 评论关闭
View Code

#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>

#define STACK_LIMIT 5 //maximum element size for stack.
#define N 100 // # of cycle for processes.

#define SHM_KEY ((key_t)0x10) //key for shared memory
#define SEM_KEY ((key_t)0x20) //key for semaphore

union semun { int val; struct semid_ds *buf; unsigned short *array; };

void set_sem_value( int semid, int i, int val )
{
union semun initval;
initval.val=val;
semctl( semid,i, SETVAL,initval);
}

struct sembuf op_lock[2]={
0,0,0, //wait until sem #0 becomes 0
0,1,SEM_UNDO //then increment sem #0 by 1
};

struct sembuf op_unlock[1]={ 0,-1,SEM_UNDO //decr sem #0 by 1
};

typedef struct
{
int top;
int home[STACK_LIMIT];
}Stack;

//necessary function declarions.
int isFull( Stack* );
int isEmpty( Stack* );
int push( Stack*, int );
int pop( Stack* );
int generate_number( int, int );

void wait_and_lock( int semid ){ semop( semid,op_lock,2); }
void signal_and_unlock( int semid ){ semop( semid,op_unlock,1); }

main()
{
Stack *sp;
int produced, i,index,w;
int shmid,semid, pid;
//create a shared memory area which will be used as stack
shmid= shmget( SHM_KEY, sizeof(Stack), IPC_CREAT | 0600);
//attach created shared area to the process.
sp=(Stack *)shmat( shmid, 0,0);
sp->top=-1; //initialize stack top

//create a semaphore for process synchronization
semid= semget( SEM_KEY,1,IPC_CREAT );
set_sem_value(semid,0,1); //set initial value of semaphore
//unlock the semaphore to allow first process access the stack.
signal_and_unlock( semid );

pid=fork(); //create producer process
if(pid==0)
{//producer
printf("\nProducer Started");

for( i=0; i<N; i++)
{
while( isFull(sp) )
;//while buffer is full, do NOTHING.
//wait untill no process working on shared area
//gain access then lock access for other processes.
wait_and_lock( semid );
/*critical section starts*/
produced = generate_number(11,41);
printf("\nProduced: %d",produced);
push( sp,produced );
/*critical section ends*/
//unlock access to shared area for other processes.
signal_and_unlock( semid );
sleep( generate_number(0,2) );
}
printf("\nProducer Exited\n");
exit(0);
}
pid=fork();//create consumer process
if(pid==0)
{
printf("\nConsumer Started");
for( i=0; i<N; i++)
{
while( isEmpty(sp) )
;//while buffer is empty, do NOTHING.
wait_and_lock( semid );
/*critical section starts*/
printf("\nConsumed: %d", pop(sp));
/*critical section ends*/
signal_and_unlock( semid );
sleep(generate_number(0,2));
}
printf("\nConsumer Exited\n");
exit(0);
}

printf("\nBuffer shower Started");
for( i=0; i<N; i++ )
{ //this part of the code, shows contents of stack
if( !isEmpty(sp) ) //if there is any info in stack, show.
{
wait_and_lock( semid );
printf("\nContents of Buffer: [");
for( index =0; index<= sp->top; index++ )
printf(" %d",sp->home[ index ]);
printf(" ]");
signal_and_unlock( semid );

}
sleep( generate_number(1,2) );
}
printf("\nBuffer shower Exited\n");
while( (w=wait()) && w!=-1)
; //wait child processes to finish their jobs.
shmdt( sp ); //dettach the shared memory area.
shmctl(shmid, IPC_RMID,0); //remove the shared memory area
semctl(semid, IPC_RMID,0); //remove the semaphore.

}

int isFull(Stack *sp)
{
if ( sp->top == STACK_LIMIT-1) return 1;
return 0;
}
int isEmpty( Stack* sp )
{
if( sp-> top == -1) return 1;
return 0;
}
int push( Stack* sp, int value)
{
if ( isFull(sp) ) return -1;
sp->home[ ++ sp->top] = value;
return 0;
}
int pop( Stack* sp )
{
if( isEmpty(sp) ) return -1;
return sp->home[ sp->top--];
}

int generate_number( int lower, int upper)
{
return (rand()% ( upper-lower)) + lower;
}

抱歉!评论已关闭.