多任务并发-线程 线程(操作系统任务调度的最小单位)什么是线程?线程是轻量化的进程用来实现多任务并发线程是操作系统任务调度的最小单位线程由进程创建在创建时会在栈区为线程分配独立的栈区空间默认8M在同一个进程中的线程共用堆区、数据区、文本区进程线程的区别进程线程正在执行的程序轻量级的进程操作系统资源分配的最小单位操作系统任务调度的最小单位资源空间消耗大0-4G资源空间消耗小8M的栈区其他区域共享进程创建、任务切换效率低线程创建、任务切换效率高进程安全性高空间独立线程的安全性较低有共享空间进程间通信较为复杂、需要用到IPC机制线程间通信简单共享内存在相同资源平台下多进程的并发量少于多线程线程相关接口span stylebackground-color:#f8f8f8span stylecolor:#333333#include pthread.h ​ // 1. 线程的创建 // 参数: (线程ID指针, 线程属性, 线程函数入口, 传给线程函数的参数) // 返回值: 成功返回0, 失败返回错误码(非零) pthread_create(tid, NULL, thread_func, (void*)arg); ​ // 2. 线程的退出 // 参数: 线程的返回值(可由其他线程通过pthread_join接收) // 作用: 终止调用该函数的线程, 并返回retval给等待者 pthread_exit(void *retval); ​ // 3. 获取当前线程自身的ID (您留空的部分) // 返回值: 调用该函数的线程的线程ID (pthread_t类型) pthread_t pthread_self(void); ​ // 4. 等待线程结束 (线程回收) // 参数: (要等待的线程ID, 接收线程返回值的指针) // 返回值: 成功返回0, 失败返回错误码 // 作用: 阻塞调用线程, 直到目标线程终止, 并回收其资源 pthread_join(pthread_t thread, void **retval);/span/span注意链接的时候必须显式链接 -lpthread线程的分离属性分离属性不需要回收的线程称为具有分离属性的线程结束时可以被操作系统回收。非分离属性可以被其他线程回收或者结束的线程成为非分离属性的线程。默认的属性线程的互斥互斥锁 - 保护共享资源防止并发访问冲突span stylebackground-color:#f8f8f8span stylecolor:#333333pthread_mutex_init() // 初始化 pthread_mutex_lock() // 加锁阻塞 pthread_mutex_trylock() // 加锁非阻塞 pthread_mutex_unlock() // 解锁 pthread_mutex_destroy() // 销毁/span/span条件变量 - 等待某个条件成立必须配合互斥锁条件变量就是为了避免CPU空转轮询而设计的让线程在条件不满足时安心睡觉条件满足时被叫醒span stylebackground-color:#f8f8f8span stylecolor:#333333pthread_cond_init() // 初始化 pthread_cond_wait() // 等待条件自动释放锁 pthread_cond_timedwait() // 限时等待 pthread_cond_signal() // 唤醒一个等待线程 pthread_cond_broadcast() // 唤醒所有等待线程 pthread_cond_destroy() // 销毁/span/span线程间的同步机制信号量 - 管理资源数量独立使用无需互斥锁span stylebackground-color:#f8f8f8span stylecolor:#333333sem_init() // 初始化初始资源数 sem_wait() // P操作资源数-1为0则阻塞 sem_trywait() // 非阻塞版 sem_timedwait() // 限时版 sem_post() // V操作资源数1唤醒等待者 sem_getvalue() // 获取当前计数 sem_destroy() // 销毁/span/span死锁的产生条件死锁是指两个或多个线程进程互相等待对方持有的资源导致所有线程都无法继续执行。四个必要条件必须同时满足条件说明比喻1. 互斥Mutual Exclusion资源一次只能被一个线程占用厕所只有一间一次只能进一个人2. 持有并等待Hold and Wait线程持有资源的同时等待其他资源你占着厕所A还等着厕所B空出来3. 不可抢占No Preemption已分配的资源不能被强制剥夺别人不能把你从厕所里拽出来4. 循环等待Circular Wait线程间形成循环等待链A等BB等CC等A都在等对方让出资源只要破坏任意一个条件死锁就不会发生如何避免死锁5种策略破坏循环等待统一加锁顺序(最常用)破坏持有并等待一次性申请所有资源破坏不可抢占使用 trylock 回退使用递归锁使用更高层级的同步机制信号量管理资源计数自然避免死锁条件变量配合互斥锁使用但设计合理可避免死锁读写锁允许多个读操作并发