Итак, я смотрю на использование простой очереди производителя / потребителя в C ++.В итоге я буду использовать boost для многопоточности, но этот пример просто использует pthreads.Я также в конечном итоге использую гораздо более ОО подход, но я думаю, что это затенило бы детали, которые меня интересуют в данный момент.
В любом случае, особые проблемы, о которых я беспокоюсь, это
- Поскольку этот код использует push_back и pop_front из std :: deque - он, вероятно, выполняет распределение и освобождение базовых данных в разных потоках - я считаю, что это плохо (неопределенное поведение) - какой самый простой способ избежать этого?
- Ничто не помечено как изменчивое.Но важные биты защищены мьютексом.Нужно ли помечать что-либо как изменчивое и если да, то что?- Я не думаю, что делаю, поскольку считаю, что мьютекс содержит соответствующие барьеры памяти и т. Д., Но я не уверен.
Есть ли какие-либо другие вопиющие проблемы?код:
#include <pthread.h>
#include <deque>
#include <iostream>
struct Data
{
std::deque<int> * q;
pthread_mutex_t * mutex;
};
void* producer( void* arg )
{
std::deque<int> &q = *(static_cast<Data*>(arg)->q);
pthread_mutex_t * m = (static_cast<Data*>(arg)->mutex);
for(unsigned int i=0; i<100; ++i)
{
pthread_mutex_lock( m );
q.push_back( i );
std::cout<<"Producing "<<i<<std::endl;
pthread_mutex_unlock( m );
}
return NULL;
}
void* consumer( void * arg )
{
std::deque<int> &q = *(static_cast<Data*>(arg)->q);
pthread_mutex_t * m = (static_cast<Data*>(arg)->mutex);
for(unsigned int i=0; i<100; ++i)
{
pthread_mutex_lock( m );
int v = q.front();
q.pop_front();
std::cout<<"Consuming "<<v<<std::endl;
pthread_mutex_unlock( m );
}
return NULL;
}
int main()
{
Data d;
std::deque<int> q;
d.q = &q;
pthread_mutex_t mutex;
pthread_mutex_init( &mutex, NULL );
d.mutex = & mutex;
pthread_t producer_thread;
pthread_t consumer_thread;
pthread_create( &producer_thread, NULL, producer, &d );
pthread_create( &consumer_thread, NULL, consumer, &d );
pthread_join( producer_thread, NULL );
pthread_join( consumer_thread, NULL );
}
РЕДАКТИРОВАТЬ:
Я закончил тем, что выбросил эту реализацию, я сейчас использую модифицированную версию кода из здесь Энтони Уильямс.Мою модифицированную версию можно найти здесь Эта модифицированная версия использует более разумный подход, основанный на переменных условий.