2010-08-22 234 views
0

我的消費者,生產者程序出現問題,它似乎已加載,但返回了分段錯誤。我已經嘗試了一切來解決它,但仍然失敗!對任何幫助都會很有幫助。 注意;代碼真的很多,如果有人希望測試,semaphore.h代碼就在其中。而其餘的代碼就像這裏一樣。我在Unix機器上運行它。消費者生產者問題

 //----------------SEMOPHORE.H-------------------------- 
    /*********************** semaphore.h ****************************/ 
    #define SEM_NAME "semaphore.h",'a' 
    #define SEM_MAX 3 
    #define FREE  0 
    #define DATA  1 
    #define ROOM  2 
    #define S_WAIT -1 
    #define S_SIGNAL 1 
    #define NO_EVENT -1 

    int sem_config(int, int); 
    int sem_wait(int, int); 
    int sem_signal(int, int); 

    //----------------Producer----------------------- 
    #include<stdio.h> 
    #include"semaphore.h" 
    #include"shbuf.h" 
    # include <string.h> 
    # include "shbuf.h" 

    void myadd(); 

    main() 
    { 
     sem_config(DATA, FREE); 
     myadd(); 
     sem_signal(DATA,S_SIGNAL); 
     return 0; 
    } 
    void myadd() 
    { 
     char str[80]; 
     char discard; 
     printf("you can type a message for the producer."\n); 
     printf("Producing message : "); 
     scanf("%s%c", str, &discard); 
     q_add(strlen(str) , str); 
    } 
    //---------------------------CONSUMER--------------------------- 
    #include<stdio.h> 
    #include"semaphore.h" 
    #include"shbuf.h" 

    # include <string.h> 
    # include "shbuf.h" 

    void myremove(); 

    main() 
    { 
    sem_wait(DATA, S_WAIT); 
    myremove(); 
    sem_signal(DATA,S_SIGNAL); 

    return 0; 
    } 

    void myremove() 
    { 
     char str[80]; 
     if(q_items() > 0) 
     { 
     q_remove(1 , str); 
     str[1] = 0; 
     printf("%s\n", str); 
     } 
    } 
    //-------------------------------SEMAPHORE.C-------------------------------------- 
    #include <sys/types.h> 
    #include <sys/ipc.h> 
    #include <sys/sem.h> 
    #include "semaphore.h" 

    static int sem_id; 

    static union semun 
     { 
      int val; /* value for SETVAL */ 
      struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */ 
      ushort array[1]; /* array for GETALL & SETALL, used in setting or retrieving all semaphorevalues in a set.*/ 
     } sem_attr; 

    static struct sembuf asem[1]; 
    static key_t s_key; //key for shared memory 

    int sem_config(int event, int init_val) 
    { 
     int x; 
     s_key = ftok(SEM_NAME); //key for semaphore 
     //create a semaphore for process synchronization 
     if (-1 == (sem_id = semget(s_key, SEM_MAX, 0666|IPC_CREAT))) 
     { 
      perror("semget"); 
      return -1; 
     } 
     if (event == NO_EVENT) 
      return 0; /*locate semaphore only*/ 
     //set initial value of semaphore 
     sem_attr.val = init_val; 
     if (-1 == semctl(sem_id, event, SETVAL, sem_attr)) 
     { 
      perror("semctl SETVAL"); 
      return -1; 
     } 
     if (-1 == (x = semctl(sem_id, event, GETVAL, sem_attr))) 
     { 
      perror("semctl GETVAL"); 
      return -1; 
     } 
     assert(x == init_val); 
     return 0; 
    } 

    int sem_wait(int event, int nwaits) 
    { 
     asem[0].sem_num = event; 
     asem[0].sem_op = nwaits * S_WAIT; 
     asem[0].sem_flg = 0; 
     if (event == NO_EVENT) /*remove semaphore set*/ 
      if (-1 == semctl(sem_id, 0, IPC_RMID, sem_attr)) 
      { 
       perror("semctl IPC_RMID"); 
       return -1; 
      } 
      else 
       return 0; 
     if (-1 == semop(sem_id, asem, 1)) 
     { 
      perror("semop"); 
      return -1; 
     } 
     return 0; 
    } 

    int sem_signal(int event, int nsignals) 
    { 
     asem[0].sem_num = event; 
     asem[0].sem_op = nsignals * S_SIGNAL; 
     asem[0].sem_flg = 0; 
     if (event == NO_EVENT) 
      if (-1 == semctl(sem_id, 0, IPC_RMID, sem_attr)) 
      { 
       perror("semctl IPC_RMID"); 
       return -1; 
      } 
      else 
       return 0; 
     if (-1 == semop(sem_id, asem, 1)) 
     { 
      perror("semop"); 
      return -1; 
     } 
     return 0; 
    } 
+0

你能解釋一下特別的失敗嗎? – 2010-08-22 08:20:02

+0

你從哪裏得到過錯?你可以嘗試在代碼中插入'printf'並查看它失敗的位置?此外,請確保您不要在'str'中寫入超過79個字符。 – dirkgently 2010-08-22 08:20:28

+0

當我運行測試文件時,兩個終端打開,消費者帶有分割結果。當我向生產者輸入一些信息時,再次分割錯誤。看起來我並不善於處理記憶。我不能確定我們的真相在哪裏 – 2010-08-22 09:25:53

回答

3

一般來說,調試段錯誤的最好方式是通過與-g標誌編譯和像GDB調試器中運行。它會告訴你它到底在哪裏崩潰,並讓你打印出變量的值來告訴你爲什麼。

1

編譯調試符號。如果您使用的是gcc,則使用-g3標誌作爲大多數符號。您還應該使用-Wall標誌並注意它給您的警告。嘗試使用調試器首先嚐試失敗的程序,並查看失敗的位置。

我敢打賭,問題在於你的q_removeq_add代碼,因爲那是你遺漏的代碼,並且因爲它可能使用了數組。

+0

gcc -g不會將數字作爲參數。它可以創建信息的類型,所以對於gdb它將是gcc -ggdb。 – SoapBox 2010-08-22 18:11:54

+0

@SoapBox:它可以或者是默認的調試信息格式。無論最新的矮小符號格式是什麼'-g3'用預處理器以及編譯器的信息生成調試符號,gdb都可以告訴你有關宏的信息。 – nategoose 2010-08-22 19:50:51