服务器测评网
我们一直在努力

Linux线程例子中,如何创建并同步多个线程?

Linux线程基础概念

在Linux操作系统中,线程是轻量级的执行单元,属于进程的一部分,与进程不同,线程共享同一进程的地址空间、文件描述符和信号处理等资源,这使得线程间的通信和数据共享更加高效,但同时也需要同步机制来避免竞争条件,Linux通过POSIX线程(pthread)库提供线程管理功能,开发者可以通过调用相关API创建、同步和销毁线程。

Linux线程例子中,如何创建并同步多个线程?

线程创建与基本属性

线程的创建是使用线程功能的第一步,在pthread库中,pthread_create()函数是核心接口,其原型为:

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);

thread参数用于存储新线程的ID,attr指定线程属性(如栈大小、调度策略等),若为NULL则使用默认属性,start_routine是线程的入口函数,arg是传递给入口函数的参数,以下代码创建一个简单的线程:

#include <stdio.h>
#include <pthread.h>
void* thread_func(void* arg) {
    printf("Hello from thread! Argument: %d\n", *(int*)arg);
    return NULL;
}
int main() {
    pthread_t tid;
    int num = 42;
    pthread_create(&tid, NULL, thread_func, &num);
    pthread_join(tid, NULL); // 等待线程结束
    return 0;
}

编译时需链接pthread库:gcc -o thread_example thread_example.c -lpthread

线程同步机制

由于线程共享资源,同步操作至关重要,pthread提供了多种同步工具,互斥锁(Mutex)是最常用的一种,互斥锁通过pthread_mutex_t类型实现,核心操作包括加锁(pthread_mutex_lock)、解锁(pthread_mutex_unlock)和尝试加锁(pthread_mutex_trylock),以下示例展示互斥锁保护共享变量的场景:

#include <stdio.h>
#include <pthread.h>
int counter = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void* increment(void* arg) {
    for (int i = 0; i < 1000; i++) {
        pthread_mutex_lock(&mutex);
        counter++;
        pthread_mutex_unlock(&mutex);
    }
    return NULL;
}
int main() {
    pthread_t t1, t2;
    pthread_create(&t1, NULL, increment, NULL);
    pthread_create(&t2, NULL, increment, NULL);
    pthread_join(t1, NULL);
    pthread_join(t2, NULL);
    printf("Counter: %d\n", counter); // 预期输出2000
    pthread_mutex_destroy(&mutex);
    return 0;
}

条件变量(pthread_cond_t)常与互斥锁配合使用,实现线程间的等待与通知机制,例如生产者-消费者模型。

Linux线程例子中,如何创建并同步多个线程?

线程属性与参数传递

线程属性允许自定义线程行为,通过pthread_attr_init初始化属性对象后,可设置分离状态(PTHREAD_CREATE_DETACHEDPTHREAD_CREATE_JOINABLE)、栈大小(pthread_attr_setstacksize)等,创建一个分离状态的线程:

pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_create(&tid, &attr, thread_func, NULL);
pthread_attr_destroy(&attr);

线程参数传递需注意类型安全,若传递多个参数,可使用结构体封装:

typedef struct { int a; double b; } ThreadArgs;
void* thread_func(void* arg) {
    ThreadArgs* params = (ThreadArgs*)arg;
    printf("a=%d, b=%.2f\n", params->a, params->b);
    free(params); // 动态分配的参数需释放
    return NULL;
}

在创建线程时动态分配结构体并传入,确保数据生命周期可控。

线程终止与资源清理

线程可通过三种方式终止:调用pthread_exit主动退出、入口函数返回(隐式调用pthread_exit)或被其他线程取消(pthread_cancel),线程退出时应释放其独占资源,如动态分配的内存或锁。

void* thread_func(void* arg) {
    int* data = malloc(sizeof(int));
    *data = 100;
    pthread_exit(data); // 返回动态分配的内存
}
int main() {
    pthread_t tid;
    pthread_create(&tid, NULL, thread_func, NULL);
    void* result;
    pthread_join(tid, &result);
    printf("Thread returned: %d\n", *(int*)result);
    free(result); // 主线程负责释放资源
    return 0;
}

若线程被取消,需确保取消点(如pthread_testcancel)或阻塞函数(如pthread_mutex_lock)被正确处理,避免资源泄漏。

Linux线程例子中,如何创建并同步多个线程?

线程池的实现与应用

在高并发场景下,频繁创建和销毁线程会带来性能开销,线程池通过预先创建一组线程并复用,显著提升效率,以下是一个简单线程池的框架:

#include <pthread.h>
#include <stdlib.h>
#define THREAD_POOL_SIZE 4
typedef struct { void (*task)(void*); void* arg; } Task;
typedef struct { Task* tasks; int head, tail, count; pthread_mutex_t lock; pthread_cond_t notify; pthread_t threads[THREAD_POOL_SIZE]; } ThreadPool;
void* thread_pool_worker(void* arg) {
    ThreadPool* pool = (ThreadPool*)arg;
    while (1) {
        pthread_mutex_lock(&pool->lock);
        while (pool->count == 0) pthread_cond_wait(&pool->notify, &pool->lock);
        Task task = pool->tasks[pool->head];
        pool->head = (pool->head + 1) % THREAD_POOL_SIZE;
        pool->count--;
        pthread_mutex_unlock(&pool->lock);
        task.task(task.arg);
    }
    return NULL;
}
ThreadPool* thread_pool_create(int queue_size) {
    ThreadPool* pool = malloc(sizeof(ThreadPool));
    pool->tasks = malloc(queue_size * sizeof(Task));
    pthread_mutex_init(&pool->lock, NULL);
    pthread_cond_init(&pool->notify, NULL);
    for (int i = 0; i < THREAD_POOL_SIZE; i++) pthread_create(&pool->threads[i], NULL, thread_pool_worker, pool);
    return pool;
}

线程池适用于服务器、任务调度等场景,通过thread_pool_add_task函数提交任务,由工作线程异步执行。

Linux线程通过pthread库提供了强大的并发编程能力,从基础创建到同步机制,再到线程池优化,开发者可根据需求选择合适的技术,合理使用线程能充分利用多核CPU资源,但需注意同步与资源管理,避免死锁和数据竞争,掌握线程编程是Linux系统级应用开发的重要技能。

赞(0)
未经允许不得转载:好主机测评网 » Linux线程例子中,如何创建并同步多个线程?