Pthread 将函数传递给池

发布于 2024-12-11 01:41:35 字数 1271 浏览 1 评论 0原文

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

I am working on creating a threadpool from scratch as part of an assignment and am able to create the thread pool and then pass each created thread a function that constantly loops. My question is how can I accept the input and pass it to an already executing pthread. After figuring this out I will add mutexes to lock the function to a specific thread, but I am unable to get to that part.

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);
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

风吹雨成花 2024-12-18 01:41:35

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

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

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

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

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

The best pattern that I can think of is to use some sort of queue to pass messages to the thread-pool. These messages may contain functions to be run as well as some control messages for shutting down the thread-pool. As you already have guessed, the queue will have to be thread safe.

A simple approach for the queue is to use a fixed size array which you turn into a circular buffer. The array will have a Mutex to lock it when accessing the array and a Condition Variable to awaken the thread-pool thread.

When putting an item on the queue, we lock the mutex, add to the queue and then signal the thread-pool with the Condition Variable.

Each running thread in the in the thread pool will start life by locking the mutex and waiting on the condition varaible (which automaticall unlocks the Mutex). When awoken it will remove the item from the queue, and then unlock the mutex. It is now free do its stuff. When finished it goes to sleep until re-signaled.

As general advice, avoid sharing memory between threads because this either leads to race conditions (if access is not protected) or leads to interlocking (if access is locked). Also avoid locking a mutex when performing any long running operation such as calling new (malloc), delete (free) or any system calls.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文