生产者 - 消费者多线程分段错误:核心转储

时间:2014-05-08 02:11:40

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

这是我们必须做的功课所述的段落:

  

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

     

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


#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. 我需要添加到我的生产者函数中才能以消耗模式获取它?

1 个答案:

答案 0 :(得分:0)

pthread_create将函数指针作为其第三个参数。您传递的值为pthread_t。你需要传递一个函数指针,就像你之前的调用一样。

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