在多线程编程中,线程回调是一种常见且高效的编程模式。它允许一个线程在完成某个任务后,通知另一个线程继续执行。这种模式在C语言中尤为有用,因为它提供了直接的操作系统级别的控制。本文将深入探讨C线程回调的概念、实现技巧以及一些实战案例。
线程回调的基本概念
线程回调指的是在一个线程中执行完某个任务后,通过某种机制通知另一个线程执行后续操作。这种机制通常涉及函数指针或回调函数。
回调函数
回调函数是一种特殊的函数,它作为参数传递给另一个函数。当这个函数执行完毕后,它会自动调用这个回调函数。
函数指针
函数指针是存储函数地址的变量。在C语言中,我们可以使用函数指针来间接调用函数。
C线程回调的实现技巧
使用信号量
信号量是一种同步机制,可以用来实现线程间的通信。在C语言中,我们可以使用POSIX信号量来实现线程回调。
#include <semaphore.h>
sem_t done;
void worker_thread(void *arg) {
// 执行任务
// ...
// 通知主线程任务完成
sem_post(&done);
}
int main() {
sem_init(&done, 0, 0);
pthread_t thread;
pthread_create(&thread, NULL, worker_thread, NULL);
// 等待任务完成
sem_wait(&done);
// 继续执行后续操作
// ...
sem_destroy(&done);
return 0;
}
使用条件变量
条件变量是一种同步机制,可以用来实现线程间的等待和通知。在C语言中,我们可以使用POSIX条件变量来实现线程回调。
#include <pthread.h>
pthread_mutex_t mutex;
pthread_cond_t cond;
void worker_thread(void *arg) {
pthread_mutex_lock(&mutex);
// 执行任务
// ...
// 通知主线程任务完成
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
int main() {
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond, NULL);
pthread_t thread;
pthread_create(&thread, NULL, worker_thread, NULL);
pthread_mutex_lock(&mutex);
// 等待任务完成
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
// 继续执行后续操作
// ...
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
return 0;
}
实战案例解析
案例一:生产者-消费者模型
在多线程编程中,生产者-消费者模型是一种经典的并发问题。以下是一个使用线程回调实现的生产者-消费者模型的示例。
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#define BUFFER_SIZE 10
int buffer[BUFFER_SIZE];
int in = 0, out = 0;
pthread_mutex_t mutex;
pthread_cond_t not_full;
pthread_cond_t not_empty;
void *producer(void *arg) {
while (1) {
pthread_mutex_lock(&mutex);
while (in == out) {
pthread_cond_wait(¬_full, &mutex);
}
// 生产数据
buffer[in] = rand() % 100;
in = (in + 1) % BUFFER_SIZE;
pthread_cond_signal(¬_empty);
pthread_mutex_unlock(&mutex);
}
}
void *consumer(void *arg) {
while (1) {
pthread_mutex_lock(&mutex);
while (in == out) {
pthread_cond_wait(¬_empty, &mutex);
}
// 消费数据
int data = buffer[out];
out = (out + 1) % BUFFER_SIZE;
pthread_cond_signal(¬_full);
pthread_mutex_unlock(&mutex);
// 处理数据
printf("Consumer: %d\n", data);
}
}
int main() {
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(¬_full, NULL);
pthread_cond_init(¬_empty, NULL);
pthread_t producer_thread, consumer_thread;
pthread_create(&producer_thread, NULL, producer, NULL);
pthread_create(&consumer_thread, NULL, consumer, NULL);
pthread_join(producer_thread, NULL);
pthread_join(consumer_thread, NULL);
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(¬_full);
pthread_cond_destroy(¬_empty);
return 0;
}
案例二:网络编程
在网络编程中,线程回调可以用来处理异步事件。以下是一个使用线程回调实现的TCP客户端示例。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main() {
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
perror("socket");
exit(1);
}
struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8080);
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
if (connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("connect");
exit(1);
}
char buffer[1024];
int len = read(sock, buffer, sizeof(buffer));
if (len > 0) {
printf("Received: %s\n", buffer);
}
close(sock);
return 0;
}
总结
线程回调是一种高效的多线程编程模式。通过使用信号量、条件变量等同步机制,我们可以实现线程间的通信和协作。本文介绍了线程回调的基本概念、实现技巧以及一些实战案例,希望对您有所帮助。
