Указатель памяти кучи потерян из поля указателя внутри структуры - PullRequest
0 голосов
/ 07 февраля 2019

Я пытаюсь реализовать пул потоков в C, используя библиотеку потоков POSIX.В функции, в которой инициализируется пул потоков, динамическое выделение памяти выполняется как для thpool , так и для поля jobqueue , но когда я пытаюсь получить доступ к полю Jobqueue из другой функции, значение указателя равно NULL .Вот мой код:

threadpool.h

#include <pthread.h>

typedef void *(*funcptr) (void *);

typedef enum JOBSTATUS
{
    COMPLETED,
    RUNNING,
    PENDING
} jobstatus;

typedef struct _job
{
    funcptr f;
    void *args;
} job;

typedef struct _thpool
{
    job *jobqueue;
    int jobquesize;
    int jobtail;
    int jobhead;
    int occupiedjobs;

    pthread_t *threadqueue;
    int nofthreads;
    int threadsOccupied;
    pthread_mutex_t mtx;
    pthread_cond_t q_notempty;
    pthread_cond_t q_empty;
} thpool;

thpool *createWorkers(int numofthreads, int nofjobs);

threadpool.c

#include "threadpool.h"
#include <stdlib.h>
#include <stdio.h>

void *primetest(void *args)
{
    int *k = (int *)args;
    int i, counter;
    for (i = 0; i <= *k; i++)
    {
        if (*k % i == 0)
            counter++;
    }
    return counter >= 3 ? (void *)0 : (void *)1;
}

void *dothreadWork(void *args)
{
    thpool *thp = (thpool *)args;
    funcptr f;
    void *arg;
    while (1)
    {
        pthread_mutex_lock(&(thp->mtx));
        while (thp->occupiedjobs == 0 /*&& thp->jobtail==thp->jobhead */ )
        {
            pthread_cond_wait(&thp->q_notempty, &thp->mtx);
        }
        f = thp->jobqueue[thp->jobhead].f;
        arg = thp->jobqueue[thp->jobhead].args;
        --thp->occupiedjobs;
        //if(thp->jobquesize==0)
        pthread_mutex_unlock(&(thp->mtx));
        f(arg);
    }
}

thpool *createWorkers(int numofthreads, int nofjobs)
{
    int i;
    thpool *thp = (thpool *)malloc(sizeof(thpool));
    if (thp == NULL)
    {
        return NULL;
    }
    thp->jobqueue = (job *)malloc(sizeof(job) * nofjobs);
    if (thp->jobqueue = NULL)
    {
        free(thp);
        return NULL;
    }
    thp->threadqueue = (pthread_t *)malloc(sizeof(pthread_t) * numofthreads);
    if (thp->threadqueue == NULL)
    {
        free(thp->jobqueue);
        free(thp);
        return NULL;
    }
    pthread_mutex_init(&thp->mtx, 0);
    pthread_cond_init(&thp->q_notempty, NULL);
    pthread_cond_init(&thp->q_empty, NULL);
    thp->jobquesize = nofjobs;
    thp->jobtail = thp->jobhead = 0;
    thp->occupiedjobs = 0;
    thp->threadsOccupied = 0;
    thp->nofthreads = numofthreads;
    for (i = 0; i < numofthreads; i++)
    {
        if (pthread_create(&(thp->threadqueue[i]), NULL, dothreadWork, thp) > 0)
        {
            return NULL;
        }
    }
    return thp;
}
void jobqueuepush(thpool **thp, funcptr f, void *args)
{
    printf("Jobqueue Push!");
    pthread_mutex_lock(&((*thp)->mtx));
    if ((*thp)->jobquesize == (*thp)->occupiedjobs)
    {
        pthread_mutex_unlock(&((*thp)->mtx));
        return;
    }
    if ((*thp)->jobqueue == NULL)   // The problem is here
    {
        pthread_mutex_unlock(&((*thp)->mtx));
        printf("Problem in memory allocation\n");
        return;
    }
    //(*thp)->jobqueue[(*thp)->jobtail].f = f;
    //(*thp)->jobqueue[(*thp)->jobtail].args = args;
    //++(*thp)->occupiedjobs;
    (*thp)->jobtail = ((*thp)->jobtail + 1) % ((*thp)->jobquesize);
    if ((*thp)->occupiedjobs == 1)
        pthread_cond_signal(&((*thp)->q_notempty));
    pthread_mutex_unlock(&((*thp)->mtx));

}

int main(int argc, void *argv[])
{
    thpool *p = createWorkers(4, 2);

    if (p != NULL)
    {
        int k = 4;
        jobqueuepush(&p, primetest, &k);
    }
    return (EXIT_SUCCESS);
}

Мой вопроспочему, даже если мы динамически выделяем память в куче, этот указатель выделения для jobqueue поля struct thpool , кажется, не остается в живых, хотя для thpool , который возвращается изфункция createWorkers у нас все еще есть?Что-то я здесь скучаю наверняка.

1 Ответ

0 голосов
/ 08 февраля 2019

if (thp->jobqueue = NULL) это проблема.- Ян Эбботт

...