c - 生产者-消费者多线程段错误: core dump

标签 c multithreading linked-list queue producer-consumer

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

The simulation will use a dedicated thread to read user requests (processes) from an input source. The request thread allocates space for the request and adds it to the request queue. The simulation also has dedicated threads for handling each processor. Each processor thread removes a request from the request queue and simulates running the process by waiting for a specified amount of time. As the processor thread simulates the execution of the process, it will log the process number, the start time, and the end time to a log file. When the run time is complete, the processor thread frees the request and handles another request. The threads within the simulated multiprocessor computer require producer-consumer synchronization with a single producer (the request thread) and multiple consumers (the processor threads). The queue itself must be protected with mutexes so that items are removed and added in a consistent manner. The consumers must synchronize on the requests available in the queue, so that they do not attempt to remove nonexistent requests. The request queue is not bounded because the request thread dynamically allocates space for requests as they come in.

There may be several different process queues sending processes to specific processors or groups of processors best suited for the particular job. Processing requests may be allowed to have priorities or other characteristics that affect the way in which they were printed. This implementation keeps pending requests in a request queue and threads need to be properly synchronized. You are required to design and implement a proper synchronization mechanism with the requirement that the queue can grow arbitrarily large.

<小时/>
#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. 我需要在生产者函数中添加什么才能使其进入消费模式?

最佳答案

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

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

关于c - 生产者-消费者多线程段错误: core dump,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23531576/

相关文章:

c - 导入模块——用 C 语言定制的模块

c - 为什么我在显示数据后得到垃圾值

java - java中的反向链表

c - 输入循环过早退出

c++ - 堆上的专用 std::vector 是线程安全的吗?

java - 使用JUnit测试一个反转单向链表的方法

c++ - 常量声明 - 语言差异?

c - 我怎样才能改写它而改用 char 数组?

java - 删除 java 中的 println 调用会导致逻辑错误

python - Python 线程是否打印到与主线程不同的缓冲区?