I have a programm which creates 1000 child processes. Each process should access to a int variable, which is stored in a shared memory segment. To protect the int variable I have created a semaphore:
#define _XOPEN_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/sem.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define KEY 1000
#define LOCK -1
#define UNLOCK 1
int *ptr;
int pid;
int shm_id;
int sem_id;
struct sembuf sema;
int main()
{
if( ( sem_id = semget( KEY, 1, IPC_CREAT | 0666 ) ) < 0 )
{
printf( "semid error\n" );
exit( EXIT_SUCCESS );
}
sema.sem_num = 1;
sema.sem_op = 0;
sema.sem_flg = SEM_UNDO;
if( ( shm_id = shmget( KEY, 1, IPC_CREAT | 0666 ) ) < 0 )
{
printf( "ERROR\n" );
exit( EXIT_SUCCESS );
}
ptr = shmat( shm_id, NULL, 0 );
*ptr = 0;
for( int i = 0; i < 10; ++i )
{
pid = fork();
if( pid == 0 )
{
// critical part
sema.sem_op = LOCK;
if( semop( sem_id, &sema, 1 ) < 0 )
{
printf( "ERROR\n" );
}
++( *ptr );
sema.sem_op = UNLOCK;
if( semop( sem_id, &sema, 1 ) < 0 )
{
printf( "ERROR\n" );
}
// end of the critical part
exit( EXIT_SUCCESS );
}
}
int return_stat;
enum { debug = 1 };
int corpse;
while ( ( corpse = waitpid( ( pid_t )-1, &return_stat, 0 ) ) > 0 )
if ( debug )
printf( "PID %d died 0x%.4X\n", corpse, return_stat );
//while( waitpid( pid, &return_stat, 0 ) == 0 );
printf( "value %d\n", *ptr );
shmdt( NULL );
semctl( sem_id, 1, IPC_RMID, 0 );
}
Here is an example output:
PID 7288 died 0x0000
PID 7289 died 0x0000
PID 7290 died 0x0000
PID 7291 died 0x0000
PID 7292 died 0x0000
PID 7293 died 0x0000
PID 7294 died 0x0000
PID 7295 died 0x0000
PID 7296 died 0x0000
PID 7297 died 0x0000
value 9
PID 7276 died 0x0000
PID 7277 died 0x0000
PID 7278 died 0x0000
PID 7279 died 0x0000
PID 7280 died 0x0000
PID 7281 died 0x0000
PID 7282 died 0x0000
PID 7283 died 0x0000
PID 7284 died 0x0000
PID 7285 died 0x0000
value 10
The output should be 1000 every time, but the output vary. I do not know why this piece of code does not work properly. Can somebody help me with my problem? Thank you