2010-08-22 230 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