2014-10-30 40 views
1

我的代码有一个奇怪的问题。假设使用Linux信号量防止3个“列车”同时进入轨道。所以输出必须是这样的: ENTRA秘鲁 售秘鲁 ENTRA玻利维亚 售玻利维亚 ENTRA哥伦比亚 出售哥伦比亚 ... (10次)信号量只在最后工作

它doesent,首先进入他们的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

他们都是idsem,停止当前的信号... -1和1是添加或价值。减去的信号。通过零在哪里?...我在这里试过: sops = {semid,-1,1}; ---> sops = {0,-1,1}; 但它没有工作): – 2014-10-31 00:05:34

回答

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); 
} 
+0

感谢您的帮助....什么是SEM_R和SEM_A,因为它会产生编译错误D: – 2014-10-31 00:13:57

+0

这些在中定义。 '#define SEM_A 0200'' #define SEM_R 0400'请注意它们是八进制常量,所以前导零非常重要。 – user3386109 2014-10-31 00:17:41

+0

这是许可证吗?写作和阅读? (预先感谢您提供的所有帮助) – 2014-10-31 01:21:28