当前位置: 首页 > article >正文

Linux下多线程编程

 

目录

原理

1. 线程与进程的区别

2. 线程的调度

3. 线程的状态

4. 线程的同步与互斥

5. 线程的创建与销毁

代码实例

代码说明

编译和运行

注意事项

总结


原理

多线程是指在一个进程中同时运行多个线程,每个线程可以独立执行不同的任务。线程是操作系统调度的最小单位,多个线程共享同一个进程的内存空间和资源,但每个线程有自己的栈和寄存器状态。

1. 线程与进程的区别
  • 进程:进程是操作系统分配资源的基本单位,每个进程有独立的内存空间、文件描述符、环境变量等。进程之间的通信需要通过进程间通信(IPC)机制,如管道、消息队列、共享内存等。

  • 线程:线程是进程内的执行单元,多个线程共享进程的内存空间和资源。线程之间的通信可以通过共享内存直接进行,因此线程间的通信比进程间通信更高效。

2. 线程的调度
  • 操作系统通过调度器来决定哪个线程在哪个CPU核心上运行。线程的调度是基于时间片轮转、优先级等算法进行的。

  • 线程的上下文切换比进程的上下文切换开销小,因为线程共享进程的内存空间,不需要切换内存映射表。

3. 线程的状态
  • 就绪状态(Ready):线程已经准备好运行,等待CPU调度。

  • 运行状态(Running):线程正在CPU上执行。

  • 阻塞状态(Blocked):线程等待某个事件(如I/O操作、锁释放等)而暂停执行。

  • 终止状态(Terminated):线程执行完毕或被强制终止。

4. 线程的同步与互斥
  • 互斥锁(Mutex):用于保护共享资源,确保同一时间只有一个线程可以访问共享资源。

  • 条件变量(Condition Variable):用于线程间的通信,允许线程等待某个条件成立。

  • 信号量(Semaphore):用于控制对共享资源的访问数量。

  • 读写锁(Read-Write Lock):允许多个线程同时读取共享资源,但写操作是互斥的。

5. 线程的创建与销毁
  • 线程的创建通常通过调用操作系统提供的API(如pthread_create)来实现。

  • 线程的销毁可以通过线程函数返回、调用pthread_exitpthread_cancel来实现。

代码实例

在Linux下进行多线程编程通常使用POSIX线程库(pthread)。pthread 是Linux系统中用于创建和管理线程的标准API。下面是一个简单的多线程编程示例,展示了如何创建线程、传递参数以及等待线程完成。

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

// 线程函数,每个线程都会执行这个函数
void* thread_function(void* arg) {
    int thread_id = *((int*)arg);  // 获取传递的参数
    printf("Thread %d is running\n", thread_id);
    pthread_exit(NULL);  // 线程退出
}

int main() {
    pthread_t threads[5];  // 定义5个线程ID
    int thread_args[5];    // 定义5个线程的参数

    // 创建5个线程
    for (int i = 0; i < 5; i++) {
        thread_args[i] = i;  // 设置线程参数
        int ret = pthread_create(&threads[i], NULL, thread_function, &thread_args[i]);
        if (ret != 0) {
            printf("Error: pthread_create failed with error code %d\n", ret);
            exit(EXIT_FAILURE);
        }
    }

    // 等待所有线程完成
    for (int i = 0; i < 5; i++) {
        pthread_join(threads[i], NULL);
    }

    printf("All threads have completed.\n");
    return 0;
}

代码说明

  1. pthread_create: 用于创建一个新的线程。它接受四个参数:

    • pthread_t *thread: 指向线程ID的指针。

    • const pthread_attr_t *attr: 线程属性,通常设置为NULL表示使用默认属性。

    • void *(*start_routine) (void *): 线程执行的函数。

    • void *arg: 传递给线程函数的参数。

  2. pthread_join: 用于等待指定的线程结束。它接受两个参数:

    • pthread_t thread: 要等待的线程ID。

    • void **retval: 用于存储线程的返回值,通常设置为NULL

  3. pthread_exit: 用于终止调用它的线程。可以传递一个返回值,通常设置为NULL

  4. 线程函数: 每个线程都会执行thread_function函数。在这个函数中,线程可以执行任何任务。

编译和运行

在Linux下编译这个程序,需要使用gcc并链接pthread库:

gcc -o multi_thread_example multi_thread_example.c -lpthread

 然后运行生成的可执行文件:

./multi_thread_example

 输出示例

Thread 0 is running
Thread 1 is running
Thread 2 is running
Thread 3 is running
Thread 4 is running
All threads have completed.

注意事项

  1. 线程安全: 在多线程编程中,多个线程可能会同时访问共享资源(如全局变量、文件等),因此需要确保线程安全。可以使用互斥锁(pthread_mutex_t)或其他同步机制来保护共享资源。

  2. 线程参数: 传递给线程的参数必须确保在线程执行期间有效。通常建议使用动态分配的内存或全局变量来传递参数。

  3. 线程退出: 线程可以通过pthread_exit显式退出,或者通过返回NULL隐式退出。

  4. 线程取消: 可以使用pthread_cancel来取消一个线程,但需要注意线程的取消点和资源清理。

总结

通过这个简单的示例,你可以开始学习如何在Linux下进行多线程编程。随着你对多线程编程的深入理解,你可以探索更复杂的同步机制和线程管理技术。在其他OS环境,如Windows,嵌入式OS中理念类似,只是在API和编程思路上有差别。


http://www.kler.cn/a/525760.html

相关文章:

  • qt-C++笔记之QLine、QRect、QPainterPath、和自定义QGraphicsPathItem、QGraphicsRectItem的区别
  • .NET MAUI进行UDP通信(二)
  • 解锁豆瓣高清海报:深度爬虫与requests进阶之路
  • github制作静态网页
  • STM32标准库移植RT-Thread nano
  • 大一计算机的自学总结:异或运算
  • MySQL 事务的隔离级别
  • 一文讲解Java中的BIO、NIO、AIO之间的区别
  • 力扣动态规划-15【算法学习day.109】
  • JavaScript 进阶(上)
  • openRv1126 AI算法部署实战之——TensorFlow TFLite Pytorch ONNX等模型转换实战
  • 开源 OA 办公系统
  • AI大模型开发原理篇-9:GPT模型的概念和基本结构
  • 亚博microros小车-原生ubuntu支持系列:17 gmapping
  • 指针(C语言)从0到1掌握指针,为后续学习c++打下基础
  • 小程序-基础加强-自定义组件
  • Java Stream API中的状态性操作与陷阱
  • JSR303校验教学
  • 某盾Blackbox参数参数逆向
  • 网络安全技术简介
  • Linux gdisk 命令使用详解
  • 跨平台物联网漏洞挖掘算法评估框架设计与实现文献综述之总结与展望
  • 未来可期|在真实与虚拟之间:AI+游戏如何再造娱乐体验
  • 74-《猴面小龙兰》
  • EtherCAT主站IGH-- 22 -- IGH之fsm_sii.h/c文件解析
  • unity学习23:场景scene相关,场景信息,场景跳转