c pthreads и искажающие данные struct

#c #multithreading #struct #pthreads

#c #многопоточность #структура #pthreads

Вопрос:

Я новичок в pthreads, и мне трудно создать поток со структурой и сохранить его данные нетронутыми при повторном приведении их из указателя void.

Я потратил несколько дней на поиски, пытаясь найти причину для этого, и мне не очень повезло. Из моих двух структур (использующих два разных потока) одна корректно преобразуется в потоке, но по какой-то причине вторая этого не делает.

Структуры:

 struct Arguments {
    List linkedList;
    Node node;
    Arguments(){}
    Arguments (List *newList, Node *newNode){
        linkedList = *newList;
        pcb = *newPCB;
    }
};

struct ClockControl {
    int counter = 0;
    pthread_mutex_t lock;
};
  

Ветки:

 void *schedule(void *args){

    //Arguments *newArgs = static_cast<Arguments*>(args); <-- Tried this, doesn't work either.
    arguments *newArgs = (arguments *) args;
    List tempList = (newArgs ->linkedList);  //DATA HERE IS CORRUPTED/WRONG
    Node tempNode = (newArgs ->node);  //DATA HERE IS CORRUPTED/WRONG

    cout << "Flagged" << Lendl;

    return NULL;
}

void *clockTime(void *clock){
    //This thread works fine

    clockControl *newClock = (clockControl*) clock;
    int localVariable = 0;

    localVariable = (newClock -> counter);

    pthread_mutex_lock(amp;(newClock -> lock));
    localVariable  ;
    newClock->counter = localVariable;
    pthread_mutex_unlock(amp;(newClock -> lock));

    return NULL;
}
  

Главная:

 int main(int argc, char** argv)
{  
    pthread_t threads[NUM_THREADS];  //Defined as 5

    clockControl clock;
    clock.counter = 0;
    pthread_mutex_init(amp;clock.lock, NULL);

    //Lists are initialized with variables.    
    List pendingList = initializeList();
    List readyList = initializeList();


    Arguments *args = new Arguments(amp;readyList, amp;pendingList.head->info);

    while (clock.counter < 6000){
        pthread_create(amp;threads[1], NULL, clockTime, (void*) amp;clock);

        if (clock.counter == pendingList.head->info.timeCreated){

            pthread_create(amp;threads[0], NULL, schedule, (void*) amp;args);
                          //INSPECTING args HERE HAS ACCURATE DATA

    }

        //Clean up threads
        for (int i = 0; i < 2; i  ){
            pthread_join(threads[i],NULL);
        }
    }
}
  

Как я уже сказал, я поискал вокруг и на данный момент в значительной степени вращаю свои колеса. У меня есть подозрение, что память может быть освобождена или очищена до выполнения потока, но я не могу найти способ обойти это.

Будем признательны за любую помощь.

Комментарии:

1. Мне кажется, что цикл будет продолжать вращаться по кругу, создавая потоки. Кроме того, поток синхронизации обновляет clock.counter, который считывает основной поток выполнения, без какой-либо последовательности вообще. Это очевидное неопределенное поведение и ошибка. Слишком много проблем с показанным кодом. Я предлагаю вам начать с более простого многопоточного excersize, чем этот.

2. Это действительно больше похоже на C, чем на C , за исключением new ключевого слова…

3. @c650 Да … отправитель запроса специально запросил pthreads вместо std::threads C , и я унаследовал связанный список / код узла. Как только я запускаю потоки, остальные их части обновляются.

4. @SamVarshavchik Вот почему мы учимся.

Ответ №1:

Вы передаете адрес указателя на аргументы в свою функцию schedule. Когда вы используете amp;args , args это уже Arguments* , поэтому вы передаете Arguments** . Чтобы решить эту проблему, вы можете просто передать args саму функцию.

Также, чтобы вы знали, reinterpret_cast<Arguments*> вероятно, более уместно, чем static_cast в этих обстоятельствах.

Ответ №2:

Эти две строки кода следует поменять местами

 localVariable = (newClock -> counter);

pthread_mutex_lock(amp;(newClock -> lock)); z
  

т. е.

 pthread_mutex_lock(amp;(newClock -> lock));
localVariable = (newClock -> counter);
  

Так что это localVariable будет правильным значением, когда несколько потоков читают counter и обновляют его