【问题标题】:Producer-Consumer Multithreading segmentation fault: core dump生产者-消费者多线程分段错误:核心转储
【发布时间】:2014-05-08 02:11:39
【问题描述】:

这是我们必须做的作业中陈述的段落:

模拟将使用专用线程来读取用户请求 (进程)来自输入源。请求线程分配空间 请求并将其添加到请求队列中。模拟也 具有处理每个处理器的专用线程。每个处理器 线程从请求队列中取出一个请求并模拟运行 通过等待指定的时间量来处理该过程。作为 处理器线程模拟进程的执行,它会记录 进程号、开始时间和结束时间到日志文件。 当运行时间完成时,处理器线程释放请求 并处理另一个请求。模拟中的线程 多处理器计算机需要生产者-消费者同步 一个生产者(请求线程)和多个消费者( 处理器线程)。队列本身必须用互斥锁保护,所以 以一致的方式删除和添加项目。消费者 必须同步队列中可用的请求,以便它们 不要试图删除不存在的请求。请求队列是 没有限制,因为请求线程动态分配空间 当他们进来时请求。

可能有几个不同的进程队列将进程发送到 最适合的特定处理器或处理器组 特定的工作。处理请求可能被允许有优先级 或其他影响他们的方式的特征 打印。此实现将待处理的请求保留在请求中 队列和线程需要正确同步。你是必需的 设计和实施适当的同步机制 要求队列可以任意增长。


#include<stdio.h>
#include<pthread.h>
#include<semaphore.h>
#include<string.h>
#include<stdlib.h>
#include<malloc.h>
#include<unistd.h>
#include<time.h>

typedef struct pr_struct
{
    int owner;
    int burst_time;
    struct pr_struct *next;

} prcmd_t;
static prcmd_t *pr_head=NULL;
static prcmd_t *pr_tail=NULL;
static int pending_request=0;
static pthread_mutex_t prmutex=PTHREAD_MUTEX_INITIALIZER;

void displayQ();//this displays the queue
void initializeData();//initializes the data for the program
void *get_request(void *args);//to be calls as a thread to enqueue input requests
void *producer(void *args);//which removes a request from the process request queue and runs it
int get_number_request();//returns the number of request
int add_queue(prcmd_t *);//adds a node at the end of the request queue
int remove_queue(prcmd_t **);//removes a node for the queue


sem_t empty;//semaphores
#define EXIT 1
#define MAX_PROCS 5
#define TRUE 1

char outbaseStr [100];
int numProcessors;
FILE *outLog=NULL;
FILE *file=NULL;
FILE *outFile=NULL;
FILE *temp=NULL;
pthread_t processor;//Producer Thread ID
//pthread_t consumer[MAX_PROCS];//consumer thread ID
pthread_t consumer;

int main(int argc, char *argv[])
{
    /* Initialize Data */
    initializeData();

    printf("argc equals %d\n", argc);
    int num_processors=atoi(argv[1]);
    int case_num=atoi(argv[2]);

    printf("num_processors equals %d\n\n", num_processors);

    switch(case_num)
    {
    case 1:
        //printf("case 1\n");
        /* Reading in from the text  */
        file = fopen("temp.txt", "wr");

        /* fopen returns 0, the NULL pointer, on failure  */
        if(file==0||file==NULL)
        {
            printf("Error: couldn't open the file\n");
            exit(EXIT);
        }

        int num=3;
        int a;

        for(int i=num;i<argc;i++)
        {
            if(i%2==0)
            {
                a=atoi(argv[i]);
                //printf("(a)argv[%d] equals %d\n", i, a);
            }
            else
            {

                //printf("argv[%d] equals %d\n", i, atoi(argv[i]));
                fprintf(file, "%d %d\n", a, atoi(argv[i]));
            }
        }


        fclose(file);
        /* Create the producer thread  */
        pthread_create(&processor, NULL, get_request, (void *)file);

        break;
    case 2:

        //char filename[100];
        //filename=argv[3];
        printf("usage: %s filename\n", argv[3]);


        /* Reading in from the text  */
        file = fopen(argv[3], "r");

        /* fopen returns 0, the NULL pointer, on failure  */
        if(file==0||file==NULL)
        {
            printf("Error: couldn't open the file\n");
            exit(EXIT);
        }


        /* Create the producer thread  */
        pthread_create(&processor, NULL, get_request, (void *)file);

        break;
    default:
        printf("Error: should be either case 1 or case 2\n");
        exit(EXIT);
        break;
    }

    pthread_join(processor, NULL);


    displayQ();



    for(int i=0;i<num_processors;i++)
    {
        sprintf(outbaseStr, "%s.%ld", "processor.out", (long)(i+1));
        printf("outbaseStr equals %s\n", outbaseStr);
        outLog=fopen(outbaseStr, "w");
        if(outLog==NULL)
        {
            printf("Error: couldn't open the file\n");
            exit(EXIT);
        }

printf("debug\n");

//***************************************************************************************/
//THIS IS THE LINE OF CODE IM TALKING ABOUT
//***************************************************************************************/
        // Create the consumer threads
        pthread_create(&consumer, NULL, (void *)processor, (void *)outLog);
        //pthread_create(&consumer[i], NULL, (void *)processor, (void *)outLog);
    }


printf("after the for loop");

    for(int i=numProcessors-1;i==0;i++)
    {
        pthread_join(consumer[i], NULL);
    }


    fclose(file);

    //then theres a remove temp.txt
    if(remove("temp.txt")==0)
    {
        perror("error deleting the file");
        return 0;
    }




}
void initializeData()
{
    printf("initializeData\n");
    //Create the empty semaphore and initialize it
    sem_init(&empty, 0, MAX_PROCS);

//  pthread_attr_init(attr);
}
void *get_request(void *argv)//this produces a queue
{
    printf("get_request\n");

    prcmd_t *process;

    while(!feof(file))//if num=0 that means there are no queues and if it is zero you can't consume 0 queues
    {
        process=(prcmd_t *)malloc(sizeof(prcmd_t));
        fscanf(file, "%d %d", &process->owner, &process->burst_time);

        add_queue(process);

        int num=get_number_request();
        printf("num equals %d\n\n", num);
    };



}
void *producer(void *argv)//this consumes a queue
{

//  prcmd_t *process;
//  process=(prcmd_t *)malloc(sizeof(prcmd_t));

    printf("producer");
//  while(TRUE)
//  {

//      printf("%d %d\n", process->owner, process->burst_time);

        /* this sleep for seconds */
//      sleep(process->burst_time);




        /* this is where the sleeping from the file will go  */
        //sleep();

        /* acquire the empty lock */
//      sem_wait(&empty);
        /* acquire the mutex lock  */
//      pthread_mutex_lock(&prmutex);

        /* remove an linkedlist from the queue  */
        //remove_queue();

        /* release the mutex lock */
//      pthread_mutex_unlock(&prmutex);
        /* signal empty */
//      sem_post(&empty);

//  }
//  printf("the end of the producer");
}
int get_number_request()
{
    return pending_request;
}
int add_queue(prcmd_t *node)
{
    prcmd_t *temp;
    temp=node;


    pthread_mutex_lock(&prmutex);

    //printf("add_queue\n");


    //printf("%d %d\n", temp->owner, temp->burst_time);

    /* adding a linkedlist to a queue */
    if(pr_head==NULL)//then pr_tail==NULL
    {
        //printf("pr_head==NULL\n");

        temp->next=NULL;
        pr_head=temp;
        pr_tail=temp;
    }
    else
    {
        //printf("pr_head!=NULL\n");
        temp->next=NULL;
        pr_tail->next=temp;
        pr_tail=temp;
    }


    pending_request++;
    pthread_mutex_unlock(&prmutex);
    //printf("add_queue success\n");
    return(0);
}
void displayQ()
{
    printf("\n\ndisplayQ\n");

    prcmd_t *process=pr_head;

//      printf("%d %d\n", pr_head->owner, pr_head->burst_time);
//      pr_head=pr_head->next;
//      printf("%d %d\n", pr_head->owner, pr_head->burst_time);

    do
    {
        printf("%d %d\n", process->owner, process->burst_time);
        process=process->next;

    }while(process!=NULL);


}

每次我运行代码时,都会遇到分段错误:当我运行时核心转储

pthread_create(&consumer[i], NULL, (void *)processor, (void *)outLog)

被调用。即使我取消注释该行并使用

进行切换
pthread_create(&(consumer[i]), NULL, (void *)processor, (void *)outLog);

它仍然给我同样的错误,我似乎无法克服它,所以我可以开始处理程序的其余部分。

我的问题是:

  1. 有没有人知道如何弄清楚为什么我的程序总是给我一个分段错误:当我运行我的消费者线程时核心转储?

  2. 我必须向生产者函数添加什么才能使其处于消费模式?

【问题讨论】:

    标签: c multithreading linked-list queue producer-consumer


    【解决方案1】:

    pthread_create 将函数指针作为其第三个参数。您正在传递一个 pthread_t 值。您需要向它传递一个函数指针,就像您在之前的调用中所做的那样。

    任何时候你必须添加一个神秘的演员表,比如(void *),你真的需要确保你在做正确的事情,因为你告诉编译器你知道你在做什么。

    【讨论】:

    • 它给了我一个关于函数没有正确传递的警告,但是 (void *) 它没有再次给我警告
    • 出现警告是有原因的。通过使用(void *) 演员来掩盖它,您是在说“我知道这看起来不像一个函数,但相信我它确实是一个函数”
    • 是的,我们必须按照程序陈述的方式保留变量这一事实非常令人困惑。所有变量都很容易切换。我知道它应该看起来像另一个 pthread_create 但直到现在我才弄明白,谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-02
    • 2017-03-10
    • 2021-07-26
    • 2017-02-01
    • 1970-01-01
    相关资源
    最近更新 更多