A
Anand
I just implemented a program to solve reader writter prob. Wenever I
run the program it seems to go into S+ state and it waits there I dont
know why. When i attach gdb to one of the childs and step through for
some lines and dettach it runs for some time again ?????
The program is listed below. The listing is kind of
long
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include <time.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
extern int errno;
static pid_t *child;
static int count;
enum { reader , writter };
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *__buf;
};
void handle( int signo )
{
for( int i = 0 ; i < count ; i++ )
kill( child , SIGINT );
}
void acquire_lock( int sem_id , int s_num )
{
struct sembuf s[2];
s[0].sem_num = s[1].sem_num = s_num;
s[0].sem_flg = s[1].sem_flg = 0;
s[0].sem_op = 0;
s[1].sem_op = 1;
semop( sem_id , s , 2 );
}
void release_lock( int sem_id , int s_num )
{
union semun s;
s.val = 0;
semctl( sem_id , s_num , SETVAL , s );
}
void reader_writer( int sem_id , int shm_id )
{
while( 1 ) {
if( rand() % 2 ) {
/* becomes a writter */
/* acquire a lock of the resource */
acquire_lock( sem_id , writter );
printf( "Writing a file:%d\n" , getpid() );
sleep( rand() % 10 );
printf( "Finished writting file:%d\n" , getpid() );
/* release lock */
release_lock( sem_id , writter );
}
else {
/* become a reader */
int *rcount = (int*) shmat( shm_id , NULL /* choose any place to
attach */ , 0 );
/* acquire lock for count manip */
printf( "Acquiring read lock:%d\n" , getpid() );
acquire_lock( sem_id , reader );
printf( "Acquiring write lock:%d\n" , getpid() );
acquire_lock( sem_id , writter );
printf( "%d\n" , *rcount );
(*rcount)++;
printf( "%d\n" , *rcount );
/*release the lock for count */
printf( "Releasing read lock:%d\n" , getpid() );
release_lock( sem_id , reader );
printf( "Doing some reading on the file:%d\n" , getpid() );
sleep( rand() % 10 );
printf( "Finished reading file:%d\n" , getpid() );
/* acquire the lock for count */
printf( "Acquiring read lock:%d\n" , getpid() );
acquire_lock( sem_id , reader );
(*rcount)--;
printf( "%d\n" , *rcount );
if( !(*rcount) ) {
/* last reader process so release the writter lock */
release_lock( sem_id , writter );
}
/* release the lock on count */
printf( "Releasing read lock:%d\n" , getpid() );
release_lock( sem_id , reader );
shmdt( rcount );
sleep( 2 );
}
}
}
int main( int argc , char** argv )
{
int sem_id;
int shm_id;
count = atoi( argv[2] );
child = (pid_t*) malloc( sizeof( pid_t ) * count );
if( ( sem_id = semget( atoi( argv[1] ) , 2 , IPC_CREAT | S_IRWXU ) )
== -1 ) {
fprintf( stderr , "%s\n" , strerror( errno ) );
exit( EXIT_FAILURE );
}
if( ( shm_id = shmget( atoi( argv[1] ) , sizeof( int ) , IPC_CREAT |
S_IRWXU ) ) == -1 ) {
fprintf( stderr , "%s\n" , strerror( errno ) );
exit( EXIT_FAILURE );
}
{
/* initialize the memory segment */
int *smem = (int*) shmat( shm_id , NULL , 0 );
*smem = 0;
}
srand( ( unsigned int ) time( NULL ) );
int i = 0;
while( i < count ) {
int id;
if( !( id = fork() ) ) {
reader_writer( sem_id , shm_id );
}
else {
child[i++] = id;
sleep( 1 );
}
}
signal( SIGINT , handle );
while( 1 );
return EXIT_SUCCESS;
}
run the program it seems to go into S+ state and it waits there I dont
know why. When i attach gdb to one of the childs and step through for
some lines and dettach it runs for some time again ?????
The program is listed below. The listing is kind of
long
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include <time.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
extern int errno;
static pid_t *child;
static int count;
enum { reader , writter };
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *__buf;
};
void handle( int signo )
{
for( int i = 0 ; i < count ; i++ )
kill( child , SIGINT );
}
void acquire_lock( int sem_id , int s_num )
{
struct sembuf s[2];
s[0].sem_num = s[1].sem_num = s_num;
s[0].sem_flg = s[1].sem_flg = 0;
s[0].sem_op = 0;
s[1].sem_op = 1;
semop( sem_id , s , 2 );
}
void release_lock( int sem_id , int s_num )
{
union semun s;
s.val = 0;
semctl( sem_id , s_num , SETVAL , s );
}
void reader_writer( int sem_id , int shm_id )
{
while( 1 ) {
if( rand() % 2 ) {
/* becomes a writter */
/* acquire a lock of the resource */
acquire_lock( sem_id , writter );
printf( "Writing a file:%d\n" , getpid() );
sleep( rand() % 10 );
printf( "Finished writting file:%d\n" , getpid() );
/* release lock */
release_lock( sem_id , writter );
}
else {
/* become a reader */
int *rcount = (int*) shmat( shm_id , NULL /* choose any place to
attach */ , 0 );
/* acquire lock for count manip */
printf( "Acquiring read lock:%d\n" , getpid() );
acquire_lock( sem_id , reader );
printf( "Acquiring write lock:%d\n" , getpid() );
acquire_lock( sem_id , writter );
printf( "%d\n" , *rcount );
(*rcount)++;
printf( "%d\n" , *rcount );
/*release the lock for count */
printf( "Releasing read lock:%d\n" , getpid() );
release_lock( sem_id , reader );
printf( "Doing some reading on the file:%d\n" , getpid() );
sleep( rand() % 10 );
printf( "Finished reading file:%d\n" , getpid() );
/* acquire the lock for count */
printf( "Acquiring read lock:%d\n" , getpid() );
acquire_lock( sem_id , reader );
(*rcount)--;
printf( "%d\n" , *rcount );
if( !(*rcount) ) {
/* last reader process so release the writter lock */
release_lock( sem_id , writter );
}
/* release the lock on count */
printf( "Releasing read lock:%d\n" , getpid() );
release_lock( sem_id , reader );
shmdt( rcount );
sleep( 2 );
}
}
}
int main( int argc , char** argv )
{
int sem_id;
int shm_id;
count = atoi( argv[2] );
child = (pid_t*) malloc( sizeof( pid_t ) * count );
if( ( sem_id = semget( atoi( argv[1] ) , 2 , IPC_CREAT | S_IRWXU ) )
== -1 ) {
fprintf( stderr , "%s\n" , strerror( errno ) );
exit( EXIT_FAILURE );
}
if( ( shm_id = shmget( atoi( argv[1] ) , sizeof( int ) , IPC_CREAT |
S_IRWXU ) ) == -1 ) {
fprintf( stderr , "%s\n" , strerror( errno ) );
exit( EXIT_FAILURE );
}
{
/* initialize the memory segment */
int *smem = (int*) shmat( shm_id , NULL , 0 );
*smem = 0;
}
srand( ( unsigned int ) time( NULL ) );
int i = 0;
while( i < count ) {
int id;
if( !( id = fork() ) ) {
reader_writer( sem_id , shm_id );
}
else {
child[i++] = id;
sleep( 1 );
}
}
signal( SIGINT , handle );
while( 1 );
return EXIT_SUCCESS;
}