【问题标题】:Segmentation fault in the below c code compiled in linux以下在linux中编译的c代码中的分段错误
【发布时间】:2016-10-12 00:47:03
【问题描述】:

我们模拟了一个由一名厨师和一名厨师组成的唐杜里鸡肉自助午餐餐厅 多个客人,这类似于单个生产者/多个消费者的问题。我们 用多个线程实现一个程序,每个线程都有一个厨师或一个客人。 我们还应用了一种同步工具——信号量,它可以解决以下问题 使用多个线程同步公共资源。通过这个项目,我们将学习 如何创建多线程进程以及如何使用信号量同步线程。

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>

struct threadInfo
{
int id;
};

/* input variables */
int nofCustomers=4,item,nofChicken=3;
pthread_attr_t attr; /*Set of thread attributes*/
pthread_t chef_t,customer_t[100];
/* the semaphores */
sem_t full, empty;
void *chef(void *param); /* the producer thread */
void *customer(void *param); /* the consumer thread */

void initializeData() 
{

/* Create the full semaphore and initialize to 0 */
sem_init(&full, 0, 0);

/* Create the empty semaphore and initialize to BUFFER_SIZE */
sem_init(&empty, 0, nofChicken);

/* Get the default attributes */
pthread_attr_init(&attr);

}

制作人

 /* Producer Thread */
 void *chef(void *param) 
{
 printf("Chef Starts Cooking\n");
 while(1) 
{
  /* acquire the empty lock */
  sem_wait(&empty);

  if(insert_item()) 
  {
     fprintf(stderr, " Producer report error condition\n");
  }
  /* signal full */
  sem_post(&full);
  sleep(1);
 }
 }

消费者

 /* Consumer Thread */
 void *customer(void *param) 
 {
   int toeat=1+rand()%4,ate=0,t=nofCustomers;
   int *id=(int*)param;
   printf("Guest %d arrives and wants to eat %d food\n", id, toeat);
   while(1) 
   {
     /* aquire the full lock */
     sem_wait(&full);

     if(remove_item()) 
     {
      fprintf(stderr, "Consumer report error condition\n");
     }
     else 
     {
   ate++;
       printf("Guest %d eats a tandoori chicken[%d/%d]\n", id,ate,toeat);
      }
     if(ate==toeat)
     {
        nofCustomers--;
    printf("Guest %d finishes and exits\n",id);
     }
     if(nofCustomers==0)
     {
    printf("All guests finish eating and exit\n");
    break ;
     }
     /* signal empty */
     sem_post(&empty);
     sleep(toeat);
   }
 }

iNC 在关键部分

/* Cook food */
int insert_item() 
{
   /* When the item is not full,cook food
   increment the item*/
  if(item <= nofChicken) 
  { 
    item++;
    printf("Chef cooks one tandoori chicken.[%d/%d]\n",item,nofChicken);
    return 0;
   }
   else 
   { /* Error the items are full */
      return -1;
    }
 }

DEC 在关键部分

  /* Eat food */
 int remove_item() {
 /* When the items is/are cooked, eat the item
   i.e.., decrement the item */
  if(item > 0)
  { 
     item--;
     return 0;
   }
   else { /* Error no items */
    return -1;
   }
 }

主要功能

 int main()
 {
   /* Loop counter */
   int i;
   struct threadInfo *info;

   //input (Havent written code for input includes nofChicken andnofCustomers

   /* Initialize the app */
   initializeData();

  /* Create the producer thread */
  pthread_create(&chef_t,&attr,chef,NULL);


  /* Create the consumer threads */
  for(i = 1; i <= nofCustomers; i++) 
 {
   info->id=i;
   pthread_create(&customer_t[i],&attr,customer,(void *)info);
 }

 return 0; 
}

BOVE CODE 中的分段错误

【问题讨论】:

  • 您可以尝试在 GDB 中运行代码以准确找到发生段错误的位置吗?
  • 按照建议使用 gdb 找到准确的 seg 故障线。但是对于初学者来说:info-&gt;id=i; 可能会导致段错误,因为info 是一个未初始化的指针。其他错误包括将相同的info 指针传递给所有线程,这意味着每个线程将看到info-&gt;id 的随机值,并且main 在退出之前不会等待线程完成(pthread_join)。
  • 欢迎来到 Stack Overflow!为了帮助人们回答您的问题,您需要更具体地说明错误。请edit 您的帖子包含您从运行minimal reproducible example 获得的确切堆栈跟踪(最好使用复制+粘贴以避免转录错误)。

标签: c linux segmentation-fault semaphore producer-consumer


【解决方案1】:

首先,修复这些编译错误:

g++ -std=c++17 -fPIC -g -Wall -Wextra -Wwrite-strings -Wno-parentheses -Wpedantic -Warray-bounds -O2 -Weffc++      39988874.cpp    -o 39988874
39988874.cpp: In function ‘void* chef(void*)’:
39988874.cpp:43:25: error: ‘insert_item’ was not declared in this scope
         if (insert_item()) {
                         ^
39988874.cpp:48:16: error: ‘sleep’ was not declared in this scope
         sleep(1);
                ^
39988874.cpp:36:18: warning: unused parameter ‘param’ [-Wunused-parameter]
 void *chef(void *param)
                  ^~~~~
39988874.cpp: In function ‘void* customer(void*)’:
39988874.cpp:58:68: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int*’ [-Wformat=]
     printf("Guest %d arrives and wants to eat %d food\n", id, toeat);
                                                                    ^
39988874.cpp:63:25: error: ‘remove_item’ was not declared in this scope
         if (remove_item()) {
                         ^
39988874.cpp:67:77: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int*’ [-Wformat=]
             printf("Guest %d eats a tandoori chicken[%d/%d]\n", id,ate,toeat);
                                                                             ^
39988874.cpp:71:54: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int*’ [-Wformat=]
             printf("Guest %d finishes and exits\n",id);
                                                      ^
39988874.cpp:79:20: error: ‘sleep’ was not declared in this scope
         sleep(toeat);
                    ^
39988874.cpp:56:32: warning: unused variable ‘t’ [-Wunused-variable]
     int toeat=1+rand()%4,ate=0,t=nofCustomers;
                                ^
39988874.cpp:81:1: warning: no return statement in function returning non-void [-Wreturn-type]
 }
 ^
<builtin>: recipe for target '39988874' failed
make: *** [39988874] Error 1

(提示:sleep() 需要 #include &lt;unistd.h&gt;;另外,你需要 int id = ((threadInfo*)param)-&gt;id

解决了这些问题,你就剩下

39988874.cpp: In function ‘int main()’:
39988874.cpp:133:17: warning: ‘info’ may be used uninitialized in this function [-Wmaybe-uninitialized]
         info->id=i;
         ~~~~~~~~^~

这很明显是由

struct threadInfo *info;
/* ... */
for (i = 1; i <= nofCustomers; i++) {
    info->id=i;
}

你的问题。你需要让info指向一些有效的存储。

【讨论】:

    猜你喜欢
    • 2015-06-22
    • 1970-01-01
    • 2018-11-19
    • 1970-01-01
    • 2020-07-04
    • 2019-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多