解决死锁的方案就是采用条件变量。 通常情况下,对共享资源(比如 n)保护要用到锁操作,当一个进程进入临界区时会拿到互斥锁(lock 操作),然后其他进程拿不到互斥锁,也就无法进入临界区,因此当进程进入临界区,发现共享资源不满足继续向下执行的条件(n > 0)时,就应该释放锁,让其他进程修改共享资源,以满足自己所需的...
* PTHREAD_MUTEX_ERRORCHECK_NP,检错锁,如果同一个线程请求同一个锁,则返回EDEADLK,否则与PTHREAD_MUTEX_TIMED_NP类型动作相同。这样就保证当不允许多次加锁时不会出现最简单情况下的死锁。 * PTHREAD_MUTEX_ADAPTIVE_NP,适应锁,动作最简单的锁类型,仅等待解锁后重新竞争。 3. 锁操作 锁操作主要包括加锁 pthrea...
PTHREAD_MUTEX_ERRORCHECK_NP,检错锁,如果同一个线程请求同一个锁,则返回EDEADLK,否则与PTHREAD_MUTEX_TIMED_NP类型动作相同。这样就保证当不允许多次加锁时不会出现最简单情况下的死锁。 PTHREAD_MUTEX_ADAPTIVE_NP,适应锁,动作最简单的锁类型,仅等待解锁后重新竞争。 可以用 pthread_mutexattr_settype(pthread_mu...
第二次调用test方法的时候本来要对同一把锁进行加锁,可发现这把锁已经被加锁了,于是线程进入了休眠(pthread_mutex_t是一把互斥锁)等待解锁。线程休眠无法继续往下执行第一次加锁无法解锁于是就造成了死锁。 使用递归锁 在初始化锁的时候我们使用递归锁, pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)...
Kernel中的自旋锁不能够在能够导致睡眠的环境中使用。举个例子,一个线程A获得了自旋锁L;这个时候,发生了中断,在对应的中断处理函数B中,也尝试获得自旋锁L,就会中断处理程序进行自旋。但是原先锁的持有者只有在中断处理程序结束后,采用机会释放自旋锁,从而导致死锁。
锁的性能开销:虽然互斥锁可以有效地防止数据竞争和不一致性,但它们也会引入一定的性能开销。因此,在使用互斥锁时需要权衡同步需求和性能开销之间的关系。综上所述,pthread_mutex_t 的静态初始化是一种简单而有效的线程同步机制,但在使用时需要注意避免死锁和优先级反转等问题,并权衡同步需求和性能开销之间的关系。
* PTHREAD_MUTEX_ERRORCHECK_NP,检错锁,如果同一个线程请求同一个锁,则返回EDEADLK,否则与PTHREAD_MUTEX_TIMED_NP类型动作相同。这样就保证当不允许多次加锁时不会出现最简单情况下的死锁。 * PTHREAD_MUTEX_ADAPTIVE_NP,适应锁,动作最简单的锁类型,仅等待解锁后重新竞争。
PTHREAD_MUTEX_ERRORCHECK_NP,检错锁,如果同一个线程请求同一个锁,则返回EDEADLK,否则与PTHREAD_MUTEX_TIMED_NP类型动作相同。这样就保证当不允许多次加锁时不会出现最简单情况下的死锁。 PTHREAD_MUTEX_ADAPTIVE_NP,适应锁,动作最简单的锁类型,仅等待解锁后重新竞争。
可以在设计中避免死锁的发生。如使用pthread_mutex_timedlock函数,该函数允许线程阻塞特定时间,如果加锁失败就会返回ETIMEDOUT。函数原型如下: #include<pthread.h>#includeintpthread_mutex_timedlock(pthread_mutex_t*restrict mutex,conststructtimesec*restrict tsptr); 读写锁 读...
* PTHREAD_MUTEX_ERRORCHECK_NP,检错锁,如果同一个线程请求同一个锁,则返回EDEADLK,否则与PTHREAD_MUTEX_TIMED_NP类型动作相同。这样就保证当不允许多次加锁时不会出现最简单情况下的死锁。 * PTHREAD_MUTEX_ADAPTIVE_NP,适应锁,动作最简单的锁类型,仅等待解锁后重新竞争。