I've got a weird problem with my code. It is suppoused to use Linux Semaphores to prevent 3 "trains" to enter the track at the same time. so the output must be something like: Entra Peru Sale Peru Entra Bolivia Sale Bolivia Entra Colombia Sale Colombia ... (10 times)
And it doesent, first enter the 3 of them and then the 3 of them get out. But, at the last cycle it works as it should. So, any ideas? Heres the source code:
/*semaphore.h*/
struct sembuf {
ushort sem_num; /* semaphore index in array */
short sem_op; /* semaphore operation */
short sem_flg; /* operation flags */
};
int seminit(int idsem, int value){
int semid = semget(idsem, 1, IPC_CREAT);
return semid;
}
void semwait(int idsem){
int semid = semget(idsem, 0, IPC_EXCL);
struct sembuf sops={semid, -1, 1};
int op = semop (semid, sops, 1);
}
void semsignal(int idsem){
int semid = semget(idsem, 0, IPC_EXCL);
struct sembuf sops={semid, 1, 1};
int op = semop (semid,sops, 1);
}
And this:
/*semaforos.c*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include "semaphores.h"
#define CICLOS 10
char *pais[3]={"Peru","Bolivia","Colombia"};
int *g;
void proceso(int i)
{
int k;
int l;
int semid=seminit(i, -1);
printf("\nSEMID: %d\n",semid);
for(k=0;k<CICLOS;k++)
{
semwait(i);
//Entrada a la seccción crítica
printf("Entra %s\n",pais[i]);
fflush(stdout);
sleep(rand()%3);
printf("- %s Sale\n",pais[i]);
semsignal(i%3);
// Salida de la sección crítica
sleep(rand()%3); // Espera aleatoria fuera de la sección crítica
}
exit(0); // Termina el proceso
}
int main()
{
int pid;
int status;
int args[3];
int i;
srand(getpid());
for(i=0;i<3;i++)
{
pid=fork(); // Crea un nuevo proceso hijo que ejecuta la función proceso()
if(pid==0)
proceso(i);
}
for(i=0;i<3;i++)
pid = wait(&status);
}
To make the semaphore work correctly, the code should create one semaphore, and use that semaphore for all three processes. Your code seems to create a separate semaphore for each process. Also, after creating the semaphore, the code should initialize the value of the semaphore to 1, so that the semaphore is ready to be taken.
Here's how I would write the code
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#define SEM_RA (SEM_R | SEM_A)
#define SEM_FLAGS (SEM_RA | (SEM_RA >> 3) | (SEM_RA >> 6))
#define CICLOS 10
static void error( const char *msg )
{
perror( msg );
exit( 1 );
}
void waitSem( int semid, int semnum )
{
struct sembuf operations = { semnum, -1, 0 };
if ( semop( semid, &operations, 1 ) < 0 )
error( __func__ );
}
void signalSem( int semid, int semnum )
{
struct sembuf operations = { semnum, 1, 0 };
if ( semop( semid, &operations, 1 ) < 0 )
error( __func__ );
}
void proceso( char *pais, int semID )
{
int k;
for ( k = 0; k < CICLOS; k++ )
{
waitSem( semID, 0 );
// Entrada a la sección crítica
printf( "Entra %s ", pais );
fflush( stdout );
sleep( arc4random_uniform( 3 ) ); // Espera aleatoria dentro de la sección crítica
printf("- %s Sale\n", pais );
signalSem( semID, 0 );
// Salida de la sección crítica
sleep( arc4random_uniform( 3 ) ); // Espera aleatoria fuera de la sección crítica
}
exit(0); // Termina el proceso
}
char *paises[3] = { "Peru", "Bolivia", "Colombia" };
int main( void )
{
int i, semID, status;
pid_t pid;
// create the one semaphore that will be used by all three child processes
if ( (semID = semget( 0x1001, 1, IPC_CREAT | SEM_FLAGS )) < 0 )
error( "Unable to create semaphore" );
// set the semaphore count to 1 so it's ready to be taken
if ( semctl( semID, 0, SETVAL, 1 ) < 0 )
error( "Unable to initialize semaphore" );
for ( i = 0; i < 3; i++ )
{
pid = fork(); // Crea un nuevo proceso hijo que ejecuta la función proceso()
if ( pid == 0 )
proceso( paises[i], semID );
}
for ( i = 0; i < 3; i++ )
wait( &status );
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.