我的代码遇到了一个奇怪的问题。它被允许使用Linux信号量来防止3" train"同时进入赛道。所以输出必须是这样的: Entra秘鲁 出售秘鲁 恩特拉玻利维亚 销售玻利维亚 恩特拉哥伦比亚 销售哥伦比亚 ... (10次)
然后它首先进入其中的3个,然后其中3个退出。但是,在最后一个循环中它可以正常工作。那么,有什么想法吗?下面是源代码:
/*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);
}
而且:
/*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);
}
答案 0 :(得分:0)
要使信号量正常工作,代码应创建一个信号量,并将该信号量用于所有三个进程。您的代码似乎为每个进程创建一个单独的信号量。此外,在创建信号量之后,代码应该将信号量的值初始化为1,以便准备好采用信号量。
这是我如何编写代码
#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 );
}