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

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

Linux线程编程实例与解析

在Linux操作系统中,线程是轻量级的执行单元,共享进程资源的同时实现并发执行,与进程相比,线程的创建和切换开销更小,适合多任务处理场景,本文将通过具体代码示例,详细介绍Linux线程的创建、同步、通信及属性控制等核心内容,帮助读者深入理解线程编程的实际应用。

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

线程的创建与基本使用

Linux线程通过POSIX线程库(pthread)实现,使用前需包含<pthread.h>头文件,并链接-lpthread库,以下是一个简单的线程创建示例:

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
void* thread_func(void* arg) {
    int thread_num = *(int*)arg;
    printf("Thread %d is running\n", thread_num);
    sleep(1); // 模拟耗时操作
    printf("Thread %d is finished\n", thread_num);
    return NULL;
}
int main() {
    pthread_t tid1, tid2;
    int arg1 = 1, arg2 = 2;
    // 创建线程
    pthread_create(&tid1, NULL, thread_func, &arg1);
    pthread_create(&tid2, NULL, thread_func, &arg2);
    // 等待线程结束
    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);
    printf("Main thread finished\n");
    return 0;
}

代码解析

  1. pthread_create用于创建线程,参数包括线程ID、线程属性、线程函数及参数。
  2. pthread_join阻塞主线程,直到指定线程执行完毕,确保资源回收。
  3. 线程函数thread_func接收void*类型参数,需自行转换类型。

编译运行:

gcc -o thread_example thread_example.c -lpthread
./thread_example

输出结果可能因线程调度顺序而异,但最终会打印所有线程的执行信息。

线程同步:互斥锁与条件变量

多线程共享资源时,需通过同步机制避免竞态条件,互斥锁(pthread_mutex_t)是最常用的同步工具。

示例:互斥锁保护共享变量

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

#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 tid1, tid2;
    pthread_create(&tid1, NULL, increment, NULL);
    pthread_create(&tid2, NULL, increment, NULL);
    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);
    printf("Final counter value: %d\n", counter); // 预期输出2000
    pthread_mutex_destroy(&mutex);
    return 0;
}

解析

  • pthread_mutex_lockunlock成对使用,确保counter的递增操作原子性。
  • 初始化互斥锁可通过PTHREAD_MUTEX_INITIALIZER静态初始化,或pthread_mutex_init动态初始化。

条件变量(pthread_cond_t常与互斥锁配合,实现线程间等待/通知机制,以下示例演示生产者-消费者模型:

#include <stdio.h>
#include <pthread.h>
#define BUFFER_SIZE 5
int buffer[BUFFER_SIZE];
int count = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t prod_cond = PTHREAD_COND_INITIALIZER;
pthread_cond_t cons_cond = PTHREAD_COND_INITIALIZER;
void* producer(void* arg) {
    for (int i = 0; i < 10; i++) {
        pthread_mutex_lock(&mutex);
        while (count == BUFFER_SIZE) {
            pthread_cond_wait(&prod_cond, &mutex);
        }
        buffer[count++] = i;
        printf("Produced: %d\n", i);
        pthread_cond_signal(&cons_cond);
        pthread_mutex_unlock(&mutex);
    }
    return NULL;
}
void* consumer(void* arg) {
    for (int i = 0; i < 10; i++) {
        pthread_mutex_lock(&mutex);
        while (count == 0) {
            pthread_cond_wait(&cons_cond, &mutex);
        }
        printf("Consumed: %d\n", buffer[--count]);
        pthread_cond_signal(&prod_cond);
        pthread_mutex_unlock(&mutex);
    }
    return NULL;
}
int main() {
    pthread_t prod_tid, cons_tid;
    pthread_create(&prod_tid, NULL, producer, NULL);
    pthread_create(&cons_tid, NULL, consumer, NULL);
    pthread_join(prod_tid, NULL);
    pthread_join(cons_tid, NULL);
    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&prod_cond);
    pthread_cond_destroy(&cons_cond);
    return 0;
}

关键点

  • pthread_cond_wait会自动释放互斥锁并在等待期间阻塞,被唤醒后重新获取锁。
  • 使用while循环检查条件(而非if),防止虚假唤醒。

线程属性与分离状态

默认情况下,线程是可结合的(joinable),需通过pthread_join回收资源,若线程无需主线程等待,可设为分离状态(detached),资源由系统自动释放。

示例:设置线程分离属性

#include <stdio.h>
#include <pthread.h>
void* detached_thread(void* arg) {
    printf("Detached thread running\n");
    sleep(2);
    printf("Detached thread exiting\n");
    return NULL;
}
int main() {
    pthread_t tid;
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); // 设置分离状态
    pthread_create(&tid, &attr, detached_thread, NULL);
    pthread_attr_destroy(&attr);
    printf("Main thread doesn't wait for detached thread\n");
    sleep(3); // 确保分离线程执行完毕
    return 0;
}

说明

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

  • 分离线程无法被pthread_join,适合独立后台任务。
  • 属性设置需在线程创建前完成,通过pthread_attr_t结构体控制。

线程通信:共享内存与信号量

线程间可通过共享内存直接通信,但需同步保护,信号量(sem_t)可作为更灵活的同步工具,控制资源访问数量。

示例:使用信号量限制并发线程数

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#define MAX_THREADS 3
sem_t semaphore;
void* worker(void* arg) {
    sem_wait(&semaphore); // 获取信号量
    printf("Thread %d working\n", *(int*)arg);
    sleep(2);
    printf("Thread %d done\n", *(int*)arg);
    sem_post(&semaphore); // 释放信号量
    return NULL;
}
int main() {
    pthread_t tids[MAX_THREADS];
    int args[MAX_THREADS];
    sem_init(&semaphore, 0, 2); // 初始信号量值为2
    for (int i = 0; i < MAX_THREADS; i++) {
        args[i] = i + 1;
        pthread_create(&tids[i], NULL, worker, &args[i]);
    }
    for (int i = 0; i < MAX_THREADS; i++) {
        pthread_join(tids[i], NULL);
    }
    sem_destroy(&semaphore);
    return 0;
}

运行逻辑

  • 信号量初始值为2,最多允许2个线程同时工作。
  • sem_wait阻塞线程直到信号量可用,sem_post增加信号量值。

Linux线程编程是并发开发的核心技能,本文通过实例覆盖了线程创建、同步(互斥锁、条件变量)、属性控制及通信机制,合理使用线程能显著提升程序性能,但需注意避免死锁、竞态条件等问题,开发者应根据实际场景选择合适的同步策略,并结合线程属性优化资源管理,掌握这些技术后,可进一步探索线程池、读写锁等高级主题,构建高效的并发系统。

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