分段错误:在执行多线程程序期间转储核心

时间:2016-11-14 23:13:22

标签: c multithreading posix mutex semaphore

我意识到我的代码太冗长而且难以阅读。

你能检查我传递参数和在主体中构造参数的方式吗? 本质上,假设我有正确的“生成”和“消费”函数的实现,我想传递一个共享的循环队列和信号量和互斥量到每个生成/消费线程。

typedef struct circularQueue
{
    int *items;
    int *head;
    int *tail;
    int numProduced;
    int numConsumed;
} circularQueue;

typedef struct threadArg
{
    int id;
    circularQueue *queue;
    pthread_mutex_t *mutex;
    sem_t *spaces;
    sem_t *itemAvail;
    int numItems;
    int bufferSize;
    int numProducer;
    int numConsumer;
} threadArg;

pthread_t *producerThd;
pthread_t *consumerThd;

int main(int argc, char* argv[])
{
    pthread_attr_t attr;

    // In fo to pass to thread arg
    circularQueue *myQueue;
    pthread_mutex_t useSharedMem;
    sem_t spaces;
    sem_t itemAvail;
    int numItems;
    int bufferSize;
    int numProducer;
    int numConsumer;

    int i, j, k, l;

    if(argc != 5)
    {
        printf("Enter in 4 arguments - N B P C\n");
        return -1;
    }
    numItems = atoi(argv[1]);
    bufferSize = atoi(argv[2]);
    numProducer = atoi(argv[3]);
    numConsumer = atoi(argv[4]);

    if(numItems == 0 || bufferSize == 0 || numProducer == 0 || numConsumer == 0)
    {
        printf("Parameters should not be 0\n");
        return -1;
    }

    // Initialize list of threads
    producerThd = malloc(sizeof(pthread_t) * numProducer);
    consumerThd = malloc(sizeof(pthread_t) * numConsumer);

    // Initialize semaphores
    sem_init(&spaces, 0, bufferSize);
    sem_init(&itemAvail, 0, 0);

    // Initialize mutex
    pthread_mutex_init(&useSharedMem, NULL);

    // Initialzie thread attributes
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);


    // Initialize queue

    myQueue = (circularQueue*)malloc(sizeof(circularQueue));
    myQueue->items = (int*)malloc(sizeof(int)*bufferSize);
    myQueue->head = myQueue->items;
    myQueue->tail = myQueue->items;
    myQueue->numProduced = 0;
    myQueue->numConsumed = 0;



    // thread arguments
    for(i = 0; i < numProducer; i++)
    {
        // Initialize thraed args
        threadArg *args = (threadArg*)malloc(sizeof(threadArg));
        args->queue = (circularQueue*)malloc(sizeof(circularQueue));
        args->mutex = &useSharedMem;
        args->spaces = &spaces;
        args->itemAvail = &itemAvail;
        args->numItems = numItems;
        args->bufferSize = bufferSize;
        args->numProducer = numProducer;
        args->numConsumer = numConsumer;
        args->id = i;
        pthread_t thisThread = *(producerThd + i);
        pthread_create(&thisThread, &attr, produce, args);
    }

    for(j = 0; j < numConsumer; j++)
    {
        // Initialize thraed args
        threadArg *args = (threadArg*)malloc(sizeof(threadArg));
        args->queue = (circularQueue*)malloc(sizeof(circularQueue));
        args->mutex = &useSharedMem;
        args->spaces = &spaces;
        args->itemAvail = &itemAvail;
        args->numItems = numItems;
        args->bufferSize = bufferSize;
        args->numProducer = numProducer;
        args->numConsumer = numConsumer;
        args->id = j;
        pthread_t thisThread = *(consumerThd + i);
        pthread_create(&thisThread, &attr, consume, args);
    }

    for(k = 0; k < numProducer; k++)
    {
        pthread_join(*(producerThd+k), NULL);
    }

    printf("Finished waiting for producers\n");


    for(l = 0; l < numConsumer; l++)
    {
        pthread_join(*(consumerThd+l), NULL);
    }
    printf("Finished waiting for consumers\n");


    free(producerThd);
    free(consumerThd);
    free(myQueue->items);
    free(myQueue);
    sem_destroy(&spaces);
    sem_destroy(&itemAvail);

    fflush(stdout);
    return 0;
}

谢谢

1 个答案:

答案 0 :(得分:0)

您的代码中存在多个未定义行为的来源,您要么在不启用编译警告的情况下进行编译,要么在我认为最差的情况下忽略它们。

  1. 中的printf()说明符错误
    printf("cid %d found this item %d as valid item %d\n", myArgs->id, thisItem, validItem);
    

    因为validItemdouble,所以最后一个说明符应为%f

  2. 您的线程函数永远不会返回值,但您声明它们返回void *,这是此类函数所需的签名。

  3. 您正在释放myQueue函数中的main(),但尚未对其进行初始化,因为该代码已被注释。

  4. 您的代码也难以阅读,因为您没有一致的样式,并且您将声明与语句混合在一起,这使得一切都非常混乱,例如:确定变量的范围非常困难。

    修复代码不仅可以帮助其他人阅读,还可以帮助您解决问题并快速找到问题。