在多线程编程中,线程回调是一种常见且高效的编程模式。它允许一个线程在完成某个任务后,通知另一个线程继续执行。这种模式在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(&not_full, &mutex);
        }

        // 生产数据
        buffer[in] = rand() % 100;
        in = (in + 1) % BUFFER_SIZE;

        pthread_cond_signal(&not_empty);

        pthread_mutex_unlock(&mutex);
    }
}

void *consumer(void *arg) {
    while (1) {
        pthread_mutex_lock(&mutex);

        while (in == out) {
            pthread_cond_wait(&not_empty, &mutex);
        }

        // 消费数据
        int data = buffer[out];
        out = (out + 1) % BUFFER_SIZE;

        pthread_cond_signal(&not_full);

        pthread_mutex_unlock(&mutex);

        // 处理数据
        printf("Consumer: %d\n", data);
    }
}

int main() {
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&not_full, NULL);
    pthread_cond_init(&not_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(&not_full);
    pthread_cond_destroy(&not_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;
}

总结

线程回调是一种高效的多线程编程模式。通过使用信号量、条件变量等同步机制,我们可以实现线程间的通信和协作。本文介绍了线程回调的基本概念、实现技巧以及一些实战案例,希望对您有所帮助。