【问题标题】:Segmentation fault: core dumped during execution of multi-threaded program分段错误:多线程程序执行期间核心转储
【发布时间】:2016-11-14 23:13:22
【问题描述】:

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

你能检查一下我传递参数和在主体中构造参数的方式吗? 本质上,只要我正确实现了“生产”和“消费”功能,我想将共享循环队列以及信号量和互斥锁传递给每个生产/消费线程。

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;
}

谢谢

【问题讨论】:

  • 您知道多线程程序没有从每个线程执行代码的顺序,因此崩溃可能发生在任何线程中,因此您不能说它发生在这里或那里。此外,未定义的行为也往往是这样的,它可能会发生或不发生取决于程序正在处理的数据之类的事情,因此也无法预测何时何地会发生这种错误。
  • 这段代码很多,如果你可以用valgrind,问题会更容易找到。
  • 您的问题似乎是每个线程都有自己的互斥锁,因此它们实际上并没有像您期望的那样将彼此锁定。 (并且您为两个互斥锁调用了一次 pthread_mutex_init ,这可能是未定义的行为)

标签: c multithreading posix mutex semaphore


【解决方案1】:

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

  1. 您在

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

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

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

  3. 您在 main() 函数中释放和取消引用 myQueue,但您尚未初始化它,因为该代码已被注释。

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

修复代码不仅可以帮助其他人阅读,还可以帮助您修复它并快速发现问题。

【讨论】:

  • 您好,非常感谢您的回答。我确实意识到代码相当冗长。我将编辑问题,以便它询问有关我的代码的具体问题
猜你喜欢
  • 2012-11-19
  • 2019-09-09
  • 2018-08-30
  • 2019-01-14
  • 1970-01-01
  • 1970-01-01
  • 2016-10-27
  • 2013-05-04
  • 2017-02-18
相关资源
最近更新 更多