I am writing a mutliprocess application that will utilize a circular
buffer in a shared memory segment. I am using two semaphores to
represent the # of available slots, and the # of slots to consumer by
the server (consumer).
The apps follow this simple model.
Producer:
decrement the available_slots semaphore
do something...
increment the to_consume semaphore.
Consumer:
decrement the to_consume semaphore.
do something...
increment the available_slots semaphore.
The problem is that when I run my test programs and watch the semaphore
values, I see the available_slots semaphore continually increase? The
program will run for a while if I remove the last increment in the
consumer program, but will eventually fail with errno 34, Result to
large. Studying the output, it does not appear to me that the value of
the two semaphores ever reaches a critical point.
This simple example has been almost copied line for line from two
different books on this subject, both yielding the same results. I have
included the source to both of my test apps. If anyone can see, or
knows of something that I am just overlooking, I would very much like to
hear from you.
Thanks
Nicholas Twerdochlib
Platform info:
Sun Sparc 20 dual ROSS 125Mhz CPUs 64MB RAM
Solaris 7/2.7
GCC v2.8.1
Server/consumer source:
*****************************************************************
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>
#include <stdlib.h>
union semun {
int val;
struct semids_ds *buf;
ushort *array;
static ushort start_val[2] = {6,0};Quote:};
union semun arg;
struct sembuf acquire = {0, -1, SEM_UNDO};
struct sembuf release = {0, 1, SEM_UNDO};
int main( void ) {
int semid;
key_t SemKey = ftok( "/tmp/loggerd.sem", 'S' );
if( (semid = semget( SemKey, 2, IPC_CREAT|0666 )) != -1 ) {
arg.array = start_val;
if( semctl( semid, 0, SETALL, arg ) < 0 ) {
printf( "Failed to set semaphore initial states.\n" );
perror( "SEMCTL: " );
return -1;
}
}
while( 1 ) {
printf( "A Ready to consume: SEM %d Value: %d\n", 0, semctl(semid,
0, GETVAL, 0) );
printf( "A Ready to consume: SEM %d Value: %d\n", 1, semctl(semid,
1, GETVAL, 0) );
acquire.sem_num = 1;
if( semop( semid, &acquire, 1 ) == -1 ) {
perror( "server:main: acquire: " );
exit( 2 );
}
printf( "B Ready to consume: SEM %d Value: %d\n", 0, semctl(semid,
0, GETVAL, 0) );
printf( "B Ready to consume: SEM %d Value: %d\n", 1, semctl(semid,
1, GETVAL, 0) );
/*
release.sem_num = 0;
if( semop( semid, &release, 1 ) == -1 ) {
perror( "server:main: release: " );
exit( 2 );
}
*/
}
**************************************************************************Quote:}
Client/producer source
**************************************************************************
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>
#include <stdlib.h>
union semun {
int val;
struct semids_ds *buf;
ushort *array;
static ushort start_val[2] = {6,0};Quote:};
union semun arg;
struct sembuf acquire = {0, -1, SEM_UNDO};
struct sembuf release = {0, 1, SEM_UNDO};
int main( void ) {
int semid;
key_t SemKey = ftok( "/tmp/loggerd.sem", 'S' );
if( (semid = semget( SemKey, 2, 0)) == -1 ) {
perror( "client:main: semget: " );
exit( 2 );
}
printf( "A Ready to consume: SEM %d Value: %d\n", 0, semctl(semid, 0,
GETVAL, 0) );
printf( "A Ready to consume: SEM %d Value: %d\n", 1, semctl(semid, 1,
GETVAL, 0) );
acquire.sem_num = 0;
if( semop( semid, &acquire, 1 ) == -1 ) {
perror( "client:main: release: " );
exit( 2 );
}
printf( "B Ready to consume: SEM %d Value: %d\n", 0, semctl(semid, 0,
GETVAL, 0) );
printf( "B Ready to consume: SEM %d Value: %d\n", 1, semctl(semid, 1,
GETVAL, 0) );
release.sem_num = 1;
if( semop( semid, &release, 1 ) == -1 ) {
perror( "client:main: acquire: " );
exit( 2 );
}
***************************************************************************Quote:}