【问题标题】:Pthread Passing Function to PoolPthread 将函数传递给池
【发布时间】:2011-12-11 08:20:14
【问题描述】:

我正在从头开始创建一个线程池作为分配的一部分,并且能够创建线程池,然后将每个创建的线程传递给一个不断循环的函数。我的问题是如何接受输入并将其传递给已经执行的 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);
  }
}

【问题讨论】:

  • 共享数据+(互斥体,条件变量)应该这样做
  • 我同意,我只是不知道将 dispatch_thread 函数的 void *(dispatch_function(void *)), void *arg) 参数作为条件变量或传递让它在全球范围内声明。我不知道是否有某种基于语法的方法可以做到这一点,或者是否有一个全新的选项可用。

标签: c++ pthreads posix threadpool


【解决方案1】:

我能想到的最佳模式是使用某种队列将消息传递到线程池。这些消息可能包含要运行的函数以及一些用于关闭线程池的控制消息。正如您已经猜到的那样,队列必须是线程安全的。

队列的一种简单方法是使用固定大小的数组,将其转换为循环缓冲区。该数组将有一个 Mutex 在访问数组时将其锁定,并有一个条件变量来唤醒线程池线程。

当将一个项目放入队列时,我们锁定互斥体,添加到队列中,然后使用条件变量向线程池发出信号。

线程池中的每个正在运行的线程都将通过锁定互斥锁并等待条件变量(这会自动解锁互斥锁)来开始生命。唤醒时,它将从队列中删除该项目,然后解锁互斥锁。它现在是免费的。完成后它会进入睡眠状态,直到重新发出信号。

作为一般建议,避免在线程之间共享内存,因为这会导致竞争条件(如果访问不受保护)或导致互锁(如果访问被锁定)。在执行任何长时间运行的操作时,例如调用 new (malloc)、delete (free) 或任何系统调用,也要避免锁定互斥锁。

【讨论】:

  • 因此,如果我要使用您所描述的排队方法,我会创建一个包含函数名称以及传递给它的参数的结构。如果是这样,那么从 dispatch_function 中提取该信息的方法是什么。我在提取函数名时遇到了困难。
  • 队列将包含条目(这将是一个结构)。一个非常简单的想法是让结构包含签名 void fn(void*) 的函数点。使用 void* 的第二个参数。或者,您可以传递包含函数 void run() 的对象。给猫剥皮的方法有很多。
  • 这就是我在阅读您的评论之前所做的事情。感谢您的帮助。
猜你喜欢
  • 2011-02-09
  • 1970-01-01
  • 2021-06-01
  • 1970-01-01
  • 2013-12-10
  • 1970-01-01
  • 1970-01-01
  • 2016-01-08
  • 1970-01-01
相关资源
最近更新 更多