Функция передачи Pthread в пул - PullRequest
0 голосов
/ 20 октября 2011

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

class ThreadPool{
public:
    ThreadPool(size_t threadCount);
    int dispatch_thread(void *(dispatch_function(void *)), void *arg);
    bool thread_avail();
    int numThreads;
    pthread_t * thread;
    pthread_mutex_t * mutexes;
};


int ThreadPool::dispatch_thread(void *(dispatch_function(void *)), void *arg){

  flag = 1;
//This is where I would like to pass the function the running pthread
}

void *BusyWork(void *t)
{
  while(true){
  //This is where I would like to run the passed function from each thread
  //I can run the passed function by itself, but need to pass it to the threadpool
  }
}

ThreadPool::ThreadPool(size_t threadCount){
 pthread_t thread[threadCount];

 for(t=0; t<threadCount; t++) {
 //printf("Main: creating thread %ld\n", t);
 rc = pthread_create(&thread[t], NULL, BusyWork, (void *)t); 
 }
}

void *test_fn(void *par)
{
   cout << "in test_fn " << *(int *)par << endl;
}

int main (){
  ThreadPool th(3);
  int max = 100;

  for (int i = 0; i < 20; i++) {
    max = 100 * i;
    th.dispatch_thread(test_fn, (void *)&max);
    sleep(1);
  }
}

1 Ответ

2 голосов
/ 20 октября 2011

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

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

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

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

Как общий совет, избегайте разделения памяти между потоками, поскольку это либо приводит к условиям гонки (если доступ не защищен), либо приводит к блокировке (если доступ заблокирован),Также избегайте блокировки мьютекса при выполнении любых длительных операций, таких как вызов новых (malloc), удаление (свободных) или любых системных вызовов.

...