pthread, связанный список с двойным указателем

#c #pointers #struct #linked-list #double-pointer

#c #указатели #структура #связанный список #двойной указатель

Вопрос:

Я, наконец, добрался до создания точной модели типа потребитель-производитель для некоторого тестового приложения, которое я создаю, но последний бит вызывает у меня некоторые проблемы.

У меня настроено 2 структуры для моего приложения. Один используется для связанного списка, который используется как список работы, которую необходимо выполнить. Другой — это структура, специфичная для каждого потока, которая содержит двойной указатель на связанный список. Я не использую один указатель, так как тогда я не могу изменить указатель в одном потоке и обнаружить изменение в другом.

 //linked list struct:

typedef struct list_of_work list_of_work;
struct list_of_work {
    // information for the work 

    list_of_work        *next;

};

//thread struct:

typedef struct thread_specs {

    list_of_work         **linked_list;

    unsigned short       thread_id;

    pthread_mutex_t      *linked_list_mtx;

} thread_specs;
 

двойной указатель в thread_specs get привязан к двойному указателю на корень list_of_work структуры следующим образом:

в основном:

 list_of_work                         *root;
list_of_work                         *traveller;
pthread_t                            thread1;
thread_specs                         thread1_info;

// allocating root and some other stuff
traveller = root;
thread1_info.linked_list = amp;traveller;
 

Все это работает без предупреждений или ошибок.

теперь я продолжаю создавать свой pthread с:

 pthread_create(amp;thread1, NULL, worker, amp;thread1_info )
 

и в моем pthread я выполняю 2 приведения, 1 для приведения структуры thread_info, а другой для приведения связанного списка. ptr — мой аргумент:

 thread_specs            *thread = (thread_specs *)ptr;
list_of_work            *work_list = (list_of_work *)thread->linked_list;
list_of_work            *temp;
 

это не выдает ошибок.

Затем у меня вызывается функция list_of_work *get_work(list_of_work *ptr) , функция работает, поэтому я не буду публиковать все целиком, но, как вы можете видеть, она ожидает увидеть указатель на связанный список и возвращает указатель на тот же связанный список (который является NULL или является следующей частью работы).

Итак, я использую эту функцию, чтобы выполнить следующую часть работы следующим образом:

 temp = get_work(*work_list);
if (temp != NULL) {
    work_list = amp;temp;
    printf("thread: %d || found work, printing type of work.... ",thread->thread_id);
}
 

Теперь в этом суть. Как я могу правильно привести и передать указатель ЗА первым указателем на мою get_work() функцию, чтобы она могла делать то, что делает.

мой компилятор выдает предупреждения:

 recode.c:348:9: error: incompatible type for argument 1 of ‘get_work’
recode.c:169:14: note: expected ‘struct list_of_work *’ but argument is of typelist_of_work 

Я благодарю всех, кто может помочь мне!

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

1. thread->drives : такого элемента нет. Возможно, было бы полезно опубликовать реальный код.

2. ах, это реальный код. Я просто изменил некоторые ссылки, чтобы прояснить свои намерения

3. Приведение также неверно (и его кажущаяся необходимость должна быть сигналом о том, что это неправильно). list_of_work *work_list = (list_of_work *)thread->linked_list; должно быть list_of_work *work_list = *(thread->linked_list); , хотя, честно говоря, если вы пытаетесь совместно использовать и управлять мьютексом с одним указателем заголовка связанного списка, это не способ сделать это.

4. я впервые работаю с pthread и связанным списком… как бы вы предложили мне поделиться одним связанным списком? Единственный гораздо менее сложный способ сделать это — поделиться им по всему миру, но мне не очень нравится это делать

5. Не беспокойтесь. Я думаю, что это то, что вы пытаетесь сделать, но я, вероятно, немного упрощаю. это становится сложнее, когда у вас есть активные вставки, в то время как потоки просматривают список, но для простого многопоточного перечисления один мьютекс — это действительно все, что вам нужно. И даже не это с правильными атомарными свойствами.

Ответ №1:

Основываясь на get_work() опубликованном вами определении функции и сообщении об ошибке, эта проблема здесь:

 temp = get_work(work_list);
                ^
   /* Notice there's no dereferencing here */
 

Функция ожидает указатель на struct list_of_work , в то время как вы передаете struct list_of_work .