2014-10-30 55 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