我正在从头开始创建一个线程池作为赋值的一部分,并且能够创建线程池,然后为每个创建的线程传递一个不断循环的函数。我的问题是如何接受输入并将其传递给已经执行的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);
}
}
答案 0 :(得分:2)
我能想到的最好的模式是使用某种队列将消息传递给线程池。这些消息可能包含要运行的函数以及用于关闭线程池的一些控制消息。正如您已经猜到的那样,队列必须是线程安全的。
队列的一个简单方法是使用固定大小的数组,然后将其转换为循环缓冲区。该数组将具有一个Mutex以在访问数组时锁定它,并使用Condition Variable来唤醒线程池线程。
将项目放入队列时,我们锁定互斥锁,添加到队列中,然后使用条件变量向线程池发送信号。
线程池中的每个正在运行的线程将通过锁定互斥锁并等待条件变量(自动解锁互斥锁)来启动生命。唤醒时,它将从队列中删除该项,然后解锁互斥锁。它现在是免费的。完成后,它会进入睡眠状态,直到重新发出信号为止。
作为一般建议,避免在线程之间共享内存,因为这会导致竞争条件(如果访问不受保护)或导致互锁(如果访问被锁定)。还要避免在执行任何长时间运行操作时锁定互斥锁,例如调用new(malloc),删除(free)或任何系统调用。