2015-06-17 36 views
1

我們今天進行了一次考試,我們有一個任務來實現「火車處理程序」。命名信號只是不工作

有7個列車由一個進程分別代表。每列火車幾秒鐘後到達,檢查我們的3輛traintrack中有1輛是否可用。如果沒有,請等待... 如果曲目是免費的,請輸入並鎖定它。 住在火車站幾秒鐘,離開並解鎖它。

我和幾個朋友正試圖讓我們的程序運行,但我們不能完成它。這似乎是我們的共享內存不能正確同步的問題(信號量)。使用一個mac,所以我必須使用命名的信號量。

編譯: 「GCC -Wall -Werror -std = gnu99 -lpthread process_trains.c -o測試」

CODE:

#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指針是全局的時候也不工作。不止一列火車進入軌道... – MacHeath

+0

所以把實際的代碼放在這裏。 –

回答

0

鏈路與-pthread !!!!所有使用的信號量函數的手冊頁告訴我們>。 <

感謝大家的幫助!

對於每個有興趣的人,這是我現在的代碼。我在考試中改進了很多沒有時間的事情。這完美運行,在我的「初學者眼睛」中,這不能通過使用給定函數(信號量,共享內存......)來改進。如果是這樣,我將不勝感激&技巧;)

#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; 
}