2015-06-17 4 views
1

У нас был экзамен сегодня, и у нас была задача реализовать «поезд-обработчик».Именованный Семафор просто не работает

Есть 7 поездов, представленных одним процессом каждый. Каждый поезд прибывает через пару секунд, проверяет, доступно ли 1 из наших 3-х троек. Если нет, подождите ... Если трек свободен, введите его и заблокируйте. Оставайтесь на вокзале в течение нескольких секунд, оставьте его и откройте.

Я и несколько друзей пытаются запустить нашу программу, но мы просто не можем это сделать. Кажется, проблема в том, что наша разделяемая память не синхронизирована должным образом (семафор). Используя mac, поэтому я должен использовать именованные семафоры.

скомпилирован с: "GCC -Wall -Werror -std = gnu99 -lpthread process_trains.c -o тест"

КОД:

#include <stdlib.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <signal.h> 
#include <sys/types.h> 
#include <time.h> 
#include <sys/mman.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <semaphore.h> 
#include <sys/wait.h> 
#include <errno.h> 


sem_t *sem; 
int *shm_ptr; 



int *initShm (int size) { 
    int shm_fd = 0; 

    if((shm_fd = shm_open("/shm", O_CREAT | O_RDWR, 0777)) == -1) { 
     perror("Error creating shared memory segment!"); 
    } 

    if ((ftruncate(shm_fd, size)) == -1) { 
     perror("Error sizing shared memory segment!"); 
    } 

    return (int*) mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); 
} 


int trainAboutToArrive(int arrive, int stay, int Y){ 

    int Z=0; 

    //Zug kommt in "arrive" Sekunden an 
    sleep(arrive); 

    while (shm_ptr[Z]!=0) { 
     Z++; 
     if(Z==3){ 
      Z=0; 
     } 
    } 

    sem_wait(sem); 
    shm_ptr[Z]=1; 
    sem_post(sem); 

    printf("Zug %d ist auf Gleis %d eingefahren\n", Y, 1+Z); 

    //Zug hat einen Aufenthalt von "stay" Sekunden 
    sleep(stay); 

    sem_wait(sem); 
    shm_ptr[Z]=0; 
    sem_post(sem); 

    sem_close(sem); 

    printf("Zug %d verlässt Gleis %d\n", Y, 1+Z); 

    return EXIT_SUCCESS; 
} 

int main(int argc, char const *argv[]) { 

    shm_unlink("shm"); 

    int i=0, tracks=3, trains=7, status; 
    int arrival[]={0,0,3,2,5,4,2}; 
    int stay[]={2,3,7,2,1,4,3}; 

    off_t size = sizeof(int)*tracks; 
    shm_ptr = initShm(size); 

    if((sem = sem_open("/semap",O_CREAT,0644,1)) == SEM_FAILED) { 
     perror("client sem_open"); 
    } 

    for (i=0; i < tracks; i++) { 
     shm_ptr[i]= 0; 
    } 

    pid_t pids[trains]; 

    for (i = 0; i < trains; i++) { 
     pids[i] = fork(); 
     if(pids[i] == -1) { 
      perror("Error creating train-process!!"); 
     } else if (pids[i] == 0) { 
      trainAboutToArrive(arrival[i], stay[i], 1+i); 
      exit(0); 
     }else if (pids[i] > 0) { 

     } 
    } 

    for(i=0; i < trains; i++){ 
     waitpid(pids[i], &status, 0); 
    } 
    shm_unlink("shm"); 

    return EXIT_SUCCESS; 
} 
+1

Вам удалось скомпилировать его, по крайней мере? 'sem_t * sem;' должен быть явно глобальным. –

+1

Да компилируется отлично. И раньше он был глобальным. просто изменил эту пару минут назад. Не работал, когда sem-pointer был глобальным. Более одного поезда входит в трек ... – MacHeath

+0

Итак, поставьте здесь реальный код. –

ответ

0

Связь с -pthread !!!! man страницы всех используемых функций семафора говорит нам>. <

Спасибо за помощь!

И для всех, кто заинтересован, это мой код сейчас. Я улучшил много вещей, на которые у меня не было времени на экзамене. Это работает отлично, и в моих «новичках-глазах» это не улучшает, используя заданные функции (семафоры, общий mem ...). Если да, то я был бы благодарен за советы & уловок;)

#include <stdlib.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/mman.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <semaphore.h> 
#include <sys/wait.h> 
#include <errno.h> 

int *shm_ptr; 

int *initShm (off_t size) { 

    int shm_fd = 0; 

    if((shm_fd = shm_open("/shm", O_CREAT | O_RDWR, 0777)) == -1) { 
     perror("Error creating shared memory segment!"); 
    } 

    if ((ftruncate(shm_fd, size)) == -1) { 
     perror("Error sizing shared memory segment!"); 
    } 

    return (int*) mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); 
} 

void initSem(sem_t **plats) { 

    if((plats[0] = sem_open("/one",O_CREAT,0644,1)) == SEM_FAILED) { 
     perror("client sem_open"); 
    } 
    if((plats[1] = sem_open("/two",O_CREAT,0644,1)) == SEM_FAILED) { 
     perror("client sem_open"); 
    } 
    if((plats[2] = sem_open("/three",O_CREAT,0644,1)) == SEM_FAILED) { 
     perror("client sem_open"); 
    } 
} 


int trainAboutToArrive(int arrive, int stay, int train, sem_t **plats){ 

    srand(getpid()); 
    int platform = rand()%3; 

    sleep(arrive); 

    while (3) { 
     sem_wait(plats[platform]); 
     if(shm_ptr[platform]==0){ 
      shm_ptr[platform]=1; 
      break; 
     } 
     sem_post(plats[platform]); 

     platform = rand() % 3; 
    } 

    printf("Train %d enters platform %d\n", train, 1+platform); 

    sleep(stay); 

    shm_ptr[platform]=0; 

    printf("Train %d leaves platform %d\n", train, 1+platform); 

    sem_post(plats[platform]); 
    sem_close(plats[platform]); 

    return EXIT_SUCCESS; 

} 

int main(int argc, char const *argv[]) { 

    shm_unlink("/shm"); 
    sem_unlink("/one"); 
    sem_unlink("/two"); 
    sem_unlink("/three"); 

    int i=0, tracks=3, trains=7, status; 
    int arrival[]={0,0,3,2,5,4,2}; 
    int stay[]={2,3,7,2,1,4,3}; 
    sem_t *plats[3]; 

    off_t size = sizeof(int)*tracks; 
    shm_ptr = initShm(size); 
    initSem(plats); 

    for (i=0; i < tracks; i++) { 
     shm_ptr[i]= 0; 
    } 

    pid_t pids[trains]; 

    for (i = 0; i < trains; i++) { 
     pids[i] = fork(); 
     if(pids[i] == -1) { 
      perror("Error creating train-process!!"); 
     } else if (pids[i] == 0) { 
      trainAboutToArrive(arrival[i], stay[i], 1+i, plats); 
      exit(0); 
     }else if (pids[i] > 0) { 

     } 
    } 

    for(i=0; i < trains; i++){ 
     waitpid(pids[i], &status, 0); 
    } 

    shm_unlink("/shm"); 
    sem_unlink("/one"); 
    sem_unlink("/two"); 
    sem_unlink("/three"); 

    return EXIT_SUCCESS; 
} 
Смежные вопросы