pthread_cancel
函数用于请求取消一个线程。当调用 pthread_cancel
时,它会向指定的线程发送一个取消请求。
#include
int pthread_cancel(pthread_t thread);
thread
:要发送取消请求的线程标识符。
0
。pthread_detach
用于将线程标记为“分离”状态。分离线程(detached thread)在完成执行后会自动释放其资源,主线程不需要调用 pthread_join
来回收这些资源。
#include
int pthread_detach(pthread_t thread);
thread
: 需要被分离的线程标识符。
pthread_detach
返回 0
。分离线程会在执行结束后自动释放资源,无需其他线程调用
进程
优点
隔离性强:
安全性高:
稳定性:
适合复杂任务:
缺点
创建和销毁开销大:
通信复杂:
线程
优点
创建和销毁开销小:
通信效率高:
适合轻量级任务:
缺点
安全性较低:
同步复杂:
稳定性问题:
线程中共享的资源称为临界资源,使用临界资源的部分代码称为临界区
用于保护共享资源,确保在同一时刻只有一个线程能够访问这些资源(排他性),它是一种软件层面上 的锁。
确保同一时间只有一个线程能够进入临界区(即访问共享资源的区域)。其他线程在进入临界区前必须等待直到互斥锁被释放。保证每个线程访问时的原子性操作。
pthread_mutex_t mutex;
定义了一个名为mutex的互斥锁。
#include
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
mutex
: 指向互斥锁的指针。attr
: 互斥锁的属性,通常为 NULL
以使用默认属性阻塞形式加锁
int pthread_mutex_lock(pthread_mutex_t *mutex);
阻塞调用线程直到成功获取锁。锁定后,其他线程尝试获取该锁将被阻塞。
int pthread_mutex_trylock(pthread_mutex_t *mutex);
尝试获取锁,如果锁已被其他线程持有,则函数立即返回,而不是阻塞调用线程。
int pthread_mutex_unlock(pthread_mutex_t *mutex);
解锁互斥锁,使其他等待的线程能够获取锁。
int pthread_mutex_destroy(pthread_mutex_t *mutex);
销毁互斥锁,释放其占用的资源。需要确保没有线程在使用该互斥锁时调用。
死锁(Deadlock)是多线程或多进程编程中常见的一个问题,它指的是一组进程或线程在互相等待资源的过程中形成了一个循环依赖,导致它们都无法继续执行。简单来说,死锁是一种系统状态,在这种状态下,所有的进程或线程都在等待其他进程或线程释放资源,但由于互相等待,系统中的所有进程或线程都处于阻塞状态,无法继续执行。
死锁的形成有以下几个必要条件,只要其中任一条件不成立,死锁就不会发生:
1.互斥条件:只有对必须互斥使用的资源的争抢才会导致死锁(如哲学家的筷子、打印机设备)。
像内存、扬声器这样可以同时让多个进程使用的资源是不会导致死锁的(因为进程不用阻塞等待
这种资源)。
2.不剥夺条件:进程所获得的资源在未使用完之前,不能由其他进程强行夺走,只能主动释放。
3.请求和保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源又被其他进程占有,此时请求进程被阻塞,但又对自己已有的资源保持不放。
4.循环等待条件:存在一种进程资源的循环等待链,链中的每一个进程已获得的资源同时被下一个进程所请求。
注意!发生死锁时一定有循环等待,但是发生循环等待时未必死锁(循环等待是死锁的必要不充分件)
如果同类资源数大于1,则即使有循环等待,也未必发生死锁。但如果系统中每类资源都只有一个,那循环等待就是死锁的充分必要条件了。
死锁的避免:只要使其中一个条件不满足就无法形成死锁。