2014-10-30 2 views
1

У меня странная проблема с моим кодом. Предполагается использовать Linux-семафоры для предотвращения одновременного входа в трек 3 «поезда». поэтому выход должен быть что-то вроде: Entra Перу Продажи Перу Entra Боливии Продажи Боливии Entra Колумбии Продажи Колумбии ... (10 раз)Семафоры работают только в конце

И doesent, сначала введите 3 из них и затем 3 из них выходят. Но на последнем цикле он работает так, как должен. Итак, какие-то идеи? Heres исходный код:

/*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, чтобы остановить текущий семафор ... The -1 и 1, чтобы добавить или вычесть значение семафора. Пропустите ноль где? ... Я попробовал это здесь: sops = {semid, -1, 1}; ---> sops = {0, -1, 1}; Но это didint работа): –

ответ

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: –

+0

Те, которые определены в . '#define SEM_A 0200'' #define SEM_R 0400' Обратите внимание, что это восьмеричные константы, поэтому начальный ноль очень важен. – user3386109

+0

Это разрешение? Для написания и чтения? (Заранее благодарю за помощь) –

Смежные вопросы