C语言如何实现主线程注册回调函数,异步回调获取子线程的结果
时间: 2024-09-15 08:06:06 浏览: 35
回调函数概念及其使用
在C语言中,由于缺乏原生的异步回调机制,我们可以利用线程池、事件循环或者是互斥量、条件变量等并发工具来实现类似功能。这里提供一种基于线程池和互斥量的例子:
首先,定义一个工作队列用于存储任务,并包含结果的位置:
```c
typedef struct {
void (*func)(void* result, void* user_data);
void* result;
void* user_data;
} Task;
struct ThreadPool {
int pool_size;
pthread_t threads[pool_size];
pthread_mutex_t mutex;
pthread_cond_t cond;
queue<Task> tasks;
};
```
然后创建一个线程池并为每个任务添加回调:
```c
void* thread_pool_worker(void* pool) {
ThreadPool* p = (ThreadPool*)pool;
while (!queue_empty(&p->tasks)) {
Task task;
pthread_mutex_lock(&p->mutex);
if (!queue_get(&p->tasks, &task)) { // 如果队列为空,那么退出循环
pthread_mutex_unlock(&p->mutex);
continue;
}
pthread_mutex_unlock(&p->mutex);
// 执行任务
task.func(task.result, task.user_data);
// 更新结果并通知主线程
pthread_mutex_lock(&p->mutex);
*(task.result) = ...; // 子线程的计算结果
pthread_cond_signal(&p->cond);
pthread_mutex_unlock(&p->mutex);
}
return NULL;
}
```
在主线程中,你可以提交任务并等待结果:
```c
void register_callback(ThreadPool* pool, void (*cb)(void*), void* user_data) {
Task task;
task.func = cb;
task.result = &user_data;
task.user_data = user_data;
pthread_mutex_lock(&pool->mutex);
queue_push(&pool->tasks, task);
if (queue_size(&pool->tasks) == 1) { // 如果队列只有一个任务,启动一个新线程
pthread_create(&pool->threads[pool->current_thread++ % pool_size], NULL, thread_pool_worker, (void*)pool);
}
pthread_mutex_unlock(&pool->mutex);
pthread_cond_wait(&pool->cond, &pool->mutex); // 等待结果
}
阅读全文