Linux进程与线程(3)

发布时间:2026/8/29 19:00:32
Linux进程与线程(3) Linux线程、互斥锁与信号量一、线程基础属性分离属性线程分为可结合属性与分离属性。默认新建线程是可结合属性线程退出之后内核不会自动回收线程资源必须调用 pthread_join() 等待回收否则产生资源泄漏。分离属性线程执行结束操作系统自动回收线程所占资源不需要调用 pthread_join 。相关APIpthread_attr_init 初始化线程属性结构体pthread_attr_destroy 销毁属性结构体pthread_attr_setdetachstate 设置线程的分离状态二、多进程 vs 多线程对比运行效率多线程 多进程线程共享同一个进程地址空间线程切换开销很小进程切换需要切换完整虚拟地址空间开销大。安全性多进程 多线程进程之间地址空间完全隔离一个进程崩溃不会干扰其他进程。所有线程隶属于同一个进程任意一个线程异常崩溃整个进程直接终止其余线程全部直接结束。通信难易多线程 多进程线程天然共享全局变量、静态变量、堆内存直接读写就可以完成通信。进程内存互相隔离没有天然共享内存必须依靠管道、消息队列、共享内存等专门IPC机制。并发控制复杂度多线程 多进程多线程共享资源会出现资源竞争必须加锁保护临界代码。进程互不干涉没有竞争问题但IPC编码工作量更大。三、线程间通信与互斥锁线程依靠全局变量完成数据通信同时带来资源竞争多个线程同时读写同一份共享数据结果错乱。核心概念原子操作CPU不能被任务调度打断的最小操作一步执行完毕中途不会切走。临界区临界代码访问共享资源的那一段代码同一时刻只允许一个线程执行。互斥锁mutex用来保护临界区保证同一时间只有一个线程进入临界代码。互斥锁全套APIpthread_mutex_init 初始化互斥锁可以传入属性一般填NULL使用默认属性。pthread_mutex_destroy 销毁互斥锁释放资源。pthread_mutex_lock 上锁。如果锁已经被别人持有当前线程阻塞休眠直到拿到锁。pthread_mutex_unlock 解锁把锁释放唤醒等待这个锁的线程。死锁死锁多个线程互相持有对方需要的锁全部阻塞谁也无法继续向下运行。死锁4个必要条件4个条件同时满足才会产生死锁互斥条件资源同一时刻只能一个线程占有不可剥夺条件锁不能被别人强行抢走只能持有者主动释放请求保持线程拿着旧锁同时去申请新锁循环等待线程之间形成环状等待链条避免死锁手段使用 pthread_mutex_trylock 非阻塞上锁拿不到锁不会卡死可以主动释放已经持有的锁。多把锁时所有线程加锁顺序保持完全一致打破循环等待。四、信号量semaphore信号量本质是一个受内核保护的资源计数器可以做线程同步也可以实现进程间同步。计数器的值代表可用资源的数量资源数目≥0。信号量APIsem_initint sem_init(sem_t *sem, int pshared, unsigned int value);pshared0用于同一个进程内部多个线程之间pshared≠0用于不同进程之间value信号量初始计数值sem_destroy 销毁信号量sem_wait() P操作申请资源资源计数大于0计数减1函数直接返回。资源计数等于0线程阻塞休眠等待资源可用。sem_post() V操作释放资源信号量计数1唤醒正在等待该信号量的线程。两种典型使用场景互斥初值设置为1相当于一把锁同一时间只允许一个线程进入。同步接力初值设置0控制线程执行顺序比如ABC循环打印A执行完post唤醒BB执行完post唤醒CC再唤醒A。互斥锁主要保护共享资源解决竞争。信号量侧重线程执行顺序同步也可以实现互斥。重点总结分离属性线程不需要pthread_join运行结束自动回收默认属性必须join否则资源泄露。线程共享进程全部地址空间通信简单但存在崩溃连锁效应进程隔离安全通信复杂。互斥锁解决资源竞争保护临界区死锁四个条件全部满足才触发统一加锁顺序是最常用规避方案。sem_init第二个参数pshared决定信号量是线程用还是跨进程使用。sem_wait申请资源计数减一资源为0就阻塞sem_post释放资源计数加一唤醒等待线程。