Linux应用软件编程 线程
1. 线程基本概念线程是轻量级进程CPU 任务调度的最小单位。 线程隶属于进程一个进程至少存在 1 个主线程main 函数所在线程可以创建多个子线程。内存共享特点✅ 线程之间共享进程资源堆、全局变量、static 静态变量、代码段、文件描述符。❌ 每个线程私有自己的栈空间默认 8M、寄存器、函数局部变量。进程资源分配最小单位线程CPU 调度最小单位。进程与线程对比表对比项进程线程核心定位操作系统资源分配最小单位CPU任务调度最小单位创建开销大需要分配完整 0‑4G 虚拟内存小只分配线程私有栈切换开销大很小内存空间用户空间完全独立共享进程大部分内存仅栈私有安全性隔离性高一个进程崩溃不影响其他进程共享地址空间一个线程崩溃整个进程全部退出通信方式必须 IPC (管道、消息队列、共享内存等)直接读写全局 / 静态变量需要同步互斥保护2. 线程常用 API头文件#include pthread.h编译必须加-pthread2.1 pthread_create 创建线程int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg);参数说明thread输出参数保存线程 IDattr线程属性NULL使用默认属性start_routine线程执行函数格式固定void* func(void *)arg传给线程函数的参数无参数填NULL返回值成功返回 0失败返回非 0 错误码。注意主线程不能提前退出否则所有子线程直接销毁。2.2 pthread_self 获取自身线程 IDpthread_t pthread_self(void);在线程函数内部获取自己的线程 ID。注意pthread_t是库层面线程 id不等于内核 tid比较两个线程 id 要用pthread_equal(t1,t2)不要直接。2.3 pthread_exit 线程退出void pthread_exit(void *retval);只退出当前调用线程不会让整个进程结束。retval线程退出返回值可以被pthread_join接收。线程退出三种方式线程函数return NULL;调用pthread_exit()整个进程结束所有线程强制销毁。2.4 pthread_join 回收非分离线程阻塞int pthread_join(pthread_t thread, void **retval);功能阻塞等待目标线程执行结束回收线程栈资源。retval接收线程返回值不需要接收填NULL。默认线程属性是非分离如果不 join线程结束后资源不会释放产生类 “僵尸线程”。2.5 pthread_detach 设置分离属性int pthread_detach(pthread_t tid);设置线程为分离线程。 分离线程结束之后系统自动回收资源不能再调用 pthread_join。适用场景主线程没有机会去 join 子线程。3. 线程互斥互斥锁 pthread_mutex临界资源多个线程都能访问的资源如全局变量、全局队列、文件。 临界区访问临界资源的那一段代码。 多线程同时访问临界资源会产生竞态条件出现脏数据。互斥锁保证同一时间只允许一个线程进入临界区。pthread_mutex_t mutex; //初始化锁 pthread_mutex_init(mutex, NULL); pthread_mutex_lock(mutex); //加锁拿不到锁就阻塞 //临界区代码 访问共享资源 pthread_mutex_unlock(mutex); //解锁 pthread_mutex_destroy(mutex); //销毁锁pthread_mutex_trylock(mutex)非阻塞加锁拿不到锁直接返回错误不会卡住。4. 线程同步信号量 semaphore同步控制线程执行先后顺序也可以限制最多 N 个线程访问资源。#include semaphore.h sem_t sem; //pshared0用于线程之间value初始信号量计数 sem_init(sem, 0, 初始值); sem_wait(sem); //P操作计数‑1计数为0就阻塞等待 //业务代码 sem_post(sem); //V操作计数1唤醒等待线程 sem_destroy(sem);示例场景信号量初始值 1 → 等价互斥锁信号量初始值 N → 最多 N 个线程同时运行ATM 银行取钱例子生产者消费者ABC 顺序打印线程。5. 死锁死锁多个线程互相拿着对方需要的锁互相永久等待程序卡死。死锁四个必要条件必须全部满足才会死锁破坏任意一个就解除互斥条件资源同一时刻只能被一个线程占有锁的特性。请求与保持条件线程已经占有锁不释放又申请别的锁。不剥夺条件锁只能持有者主动 unlock别人不能强制抢走。循环等待条件多个线程形成环形等待A 拿锁 1 要锁 2B 拿锁 2 要锁 1。避免死锁方案锁 lock 与 unlock 必须成对所有线程加锁顺序保持一致破坏循环等待使用非阻塞锁pthread_mutex_trylock获取失败主动释放已有锁尽量减少多把锁嵌套使用。

相关新闻

最新新闻

日新闻

周新闻

月新闻