Linux 多线程详解

一、线程的概念

线程是操作系统调度的最小单位,它是进程中的一个执行单位。一个进程可以拥有多个线程,这些线程可以共享进程的资源,包括内存、文件等。线程之间的切换比进程之间的切换代价要小很多,也更加高效。在Linux系统中,线程的实现依赖于操作系统提供的POSIX线程库(pthread)。

二、线程的创建和销毁

线程的创建和销毁是多线程编程的基本操作。在Linux系统中,线程的创建和销毁都是通过pthread库提供的函数实现的。例如,创建一个线程可以使用pthread_create函数,销毁一个线程可以使用pthread_cancel函数。

void *thread_func(void *arg){
    printf("This is a pthread.\n");
    pthread_exit(NULL);
}
int main(){
    pthread_t tid;
    int ret = pthread_create(&tid, NULL, thread_func, NULL);  //创建一个线程
    if(ret){
        printf("Create pthread error!\n");
        return -1;
    }
    pthread_join(tid, NULL);  //等待子线程结束
    return 0;
}

在上面的示例代码中,pthread_t类型的tid变量储存着新建线程的线程ID。pthread_create函数接受四个参数,第一个参数是指向新线程标识符的指针,第二个参数用于设置线程属性,第三个参数是新线程运行的函数,第四个参数是传给函数的参数。pthread_join函数用于等待子线程结束。

三、线程同步与互斥

线程同步与互斥是多线程编程中必须掌握的概念,它们是保证多个线程安全共享数据的重要手段。Linux系统提供了多种同步和互斥机制,其中最常用的是互斥锁和条件变量。

pthread_mutex_t mutex;
pthread_cond_t cond;
void *thread_func(void *arg){
    // 模拟线程同步
    pthread_mutex_lock(&mutex);  // 加锁
    pthread_cond_wait(&cond, &mutex);  // 等待条件变量的信号
    pthread_mutex_unlock(&mutex);  // 解锁
    printf("Thread is over.\n");
    pthread_exit(NULL);
}
int main(){
    pthread_t tid;
    pthread_mutex_init(&mutex, NULL);  // 初始化互斥锁
    pthread_cond_init(&cond, NULL);  // 初始化条件变量
    int ret = pthread_create(&tid, NULL, thread_func, NULL);  // 创建一个线程
    if(ret){
        printf("Create pthread error!\n");
        return -1;
    }
    // 模拟线程同步
    sleep(5);
    pthread_cond_signal(&cond); // 发送信号
    pthread_join(tid, NULL); // 等待子线程结束
    pthread_mutex_destroy(&mutex);  // 销毁互斥锁
    pthread_cond_destroy(&cond);  // 销毁条件变量
    return 0;
}

在上面的示例代码中,使用pthread_mutex_t定义了互斥锁和pthread_cond_t定义了条件变量。pthread_mutex_lock和pthread_mutex_unlock函数用于加锁和解锁互斥锁,pthread_cond_wait函数用于等待条件变量的信号,pthread_cond_signal函数用于发送信号。

四、线程池

线程池是提高多线程执行效率的重要手段,它可以使得多个线程共享一定数量的线程资源,避免了线程频繁创建和销毁的开销。在Linux系统中,线程池的实现主要依赖于pthread库提供的线程创建、销毁和管理函数。

#define THREAD_NUM 5
#define QUEUE_SIZE 10
pthread_t threads[THREAD_NUM];
int queue[QUEUE_SIZE];
int front = 0, rear = 0;
pthread_mutex_t mutex;
pthread_cond_t cond;
void *worker_func(void *arg){
    int thread_id = *(int *)arg;
    while(1){
        pthread_mutex_lock(&mutex);  // 加锁
        while(front == rear){  // 队列为空,等待信号
            pthread_cond_wait(&cond, &mutex);
        }
        int task = queue[front++];  // 从队列中取出任务
        printf("Thread %d get task %d.\n", thread_id, task);
        pthread_mutex_unlock(&mutex);  // 解锁
        sleep(2);  // 模拟任务执行
    }
    pthread_exit(NULL);
}
int main(){
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond, NULL);
    int tids[THREAD_NUM];
    for(int i = 0; i < THREAD_NUM; i++){
        tids[i] = i + 1;
        pthread_create(&threads[i], NULL, worker_func, &tids[i]);  // 创建线程
    }
    srand(time(NULL));
    for(int i = 0; i < 20; i++){  // 向队列中添加任务
        pthread_mutex_lock(&mutex);  // 加锁
        while((rear + 1) % QUEUE_SIZE == front){  // 队列已满,等待信号
            pthread_cond_wait(&cond, &mutex);
        }
        queue[rear] = rand() % 100;  // 添加任务
        rear = (rear + 1) % QUEUE_SIZE;
        printf("Task %d added to queue.\n", i);
        pthread_mutex_unlock(&mutex);  // 解锁
        pthread_cond_signal(&cond);  // 发送信号
        sleep(1);
    }
    for(int i = 0; i < THREAD_NUM; i++){
        pthread_cancel(threads[i]);  // 结束线程
    }
    pthread_mutex_destroy(&mutex);  // 销毁互斥锁
    pthread_cond_destroy(&cond);  // 销毁条件变量
    return 0;
}

在上面的示例代码中,创建了一个固定大小的队列来储存任务,使用互斥锁保证队列的线程安全,使用条件变量通信。线程池中包括多个工作线程,它们都从队列中获取任务进行执行。主线程向队列中添加任务,使用pthread_cond_broadcast函数给所有线程发送信号,线程池的核心在于阻塞等待队列消息,并动态创建线程。

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/249916.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝小蓝
上一篇 2024-12-12 17:13
下一篇 2024-12-12 17:14

相关推荐

  • Python多线程读取数据

    本文将详细介绍多线程读取数据在Python中的实现方法以及相关知识点。 一、线程和多线程 线程是操作系统调度的最小单位。单线程程序只有一个线程,按照程序从上到下的顺序逐行执行。而多…

    编程 2025-04-29
  • 如何在Linux中添加用户并修改配置文件

    本文将从多个方面详细介绍在Linux系统下如何添加新用户并修改配置文件 一、添加新用户 在Linux系统下创建新用户非常简单,只需使用adduser命令即可。使用以下命令添加新用户…

    编程 2025-04-27
  • 多线程和多进程的应用

    多线程和多进程是现代编程中常用的技术,可以提高程序的效率和性能。本文将从不同的角度对多线程和多进程进行详细的介绍和应用。 一、多线程 vs 多进程 多线程和多进程都是为了实现程序并…

    编程 2025-04-27
  • 如何解决linux jar包 invalid or corrupt jarfile问题

    对于许多开发人员和系统管理员在Linux环境下使用Java开发过程中遇到的一个常见的问题是 invalid or corrupt jarfile(无效或损坏的jar文件)错误。当您…

    编程 2025-04-27
  • Python多线程模块实践

    本文将向大家介绍Python中的多线程模块,并通过示例代码来展示如何灵活使用线程提升程序的性能。同时,本文还将讨论Python多线程模块使用中可能遇到的一些问题及其解决方法。 一、…

    编程 2025-04-27
  • 在Linux上安装JRE并配置环境变量

    本文将从以下几个方面为您详细阐述如何在Linux系统上,通过自己账户安装JRE,并且配置环境变量。 一、安装JRE 在进行安装前,我们需要下载JRE的安装包并解压,可以从官方网站下…

    编程 2025-04-27
  • GTKAM:Linux下的照片管理器

    GTKAM是用于Linux操作系统的一款照片管理器,它支持多种相机及存储设备,并提供了一系列强大的工具,让用户可以方便地浏览、管理、编辑和导出照片。本文将从多个方面对GTKAM进行…

    编程 2025-04-27
  • Linux sync详解

    一、sync概述 sync是Linux中一个非常重要的命令,它可以将文件系统缓存中的内容,强制写入磁盘中。在执行sync之前,所有的文件系统更新将不会立即写入磁盘,而是先缓存在内存…

    编程 2025-04-25
  • 神经网络代码详解

    神经网络作为一种人工智能技术,被广泛应用于语音识别、图像识别、自然语言处理等领域。而神经网络的模型编写,离不开代码。本文将从多个方面详细阐述神经网络模型编写的代码技术。 一、神经网…

    编程 2025-04-25
  • Java BigDecimal 精度详解

    一、基础概念 Java BigDecimal 是一个用于高精度计算的类。普通的 double 或 float 类型只能精确表示有限的数字,而对于需要高精度计算的场景,BigDeci…

    编程 2025-04-25

发表回复

登录后才能评论