Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 僵局的快速修复?_C_Linux_Multithreading_Thread Safety - Fatal编程技术网

C 僵局的快速修复?

C 僵局的快速修复?,c,linux,multithreading,thread-safety,C,Linux,Multithreading,Thread Safety,我的教科书描述了死锁,如下图所示: 其中s和t是信号量和 void P(sem_t *s); /* Wrapper function for sem_wait */ void V(sem_t *s); /* Wrapper function for sem_post */ 我可以理解这是如何工作的,如果一个线程进入死锁区域,它就不能继续前进,永远卡住。教科书中提到了互斥锁排序规则: 如果对于程序中的每对互斥体(s,t),同时持有s和t的每个线程都以相同的顺序锁定它们,则程序是无死锁的。 例如

我的教科书描述了死锁,如下图所示:

其中
s
t
是信号量和

void P(sem_t *s); /* Wrapper function for sem_wait */
void V(sem_t *s); /* Wrapper function for sem_post */
我可以理解这是如何工作的,如果一个线程进入死锁区域,它就不能继续前进,永远卡住。教科书中提到了互斥锁排序规则: 如果对于程序中的每对互斥体(s,t),同时持有s和t的每个线程都以相同的顺序锁定它们,则程序是无死锁的。 例如,我们可以通过先锁定s,然后锁定t来修复死锁 每个线程。下图显示了生成的进度图:

但我有一个快速解决方案可能有效,我不确定我是否正确:

我们可以只添加一些简单的语句,比如single
int test=0
,这将在两个禁止区域之间创建一个垂直间隙,因此线程最终可以通过该间隙,如下图所示:

我的方法在技术上正确吗

我们可以只添加一些琐碎的语句,例如single;或者P和V操作之间的int test=0,这将在两个禁止区域之间创建一个垂直间隙,因此线程最终可以通过该间隙,如下图所示

首先“;”(您希望编译器生成的代码有什么?)或
inttest=0
不会产生间隙,即使执行或线程是异步的,也不能对它们的执行进行假设,这就是为什么要使用互斥体


因此,如果需要获取多个互斥体,则必须在所有线程中以相同的顺序执行。显然,互斥锁并不是产生死锁的唯一方法,所有同步点都必须考虑进去。

书中的两张图片显示了重叠的矩形。重叠区域对应于任一线程可以同时拥有两个互斥体的事实。另一方面,您绘制的图片显示的是不重叠的矩形。如果我们以与本书图片相同的方式解释您的图片,那么非重叠性应该意味着两个线程都不能同时拥有两个互斥体

是的,重新设计代码,使任何线程一次都不会锁定多个互斥锁,这是防止线程在获取互斥锁时死锁的一种保证方法,但这也可能使程序更难有效地执行您需要它执行的任何操作。这就是反模式


关于“死锁的快速修复?”


僵局是个问题。对于体系结构问题没有快速解决方法。

像这样对死锁进行推理是不必要的复杂。死锁只是当多个线程在同一资源上等待时发生的。无需绘制图表,也无需攻读该学科的博士学位。一个常见的例子是:同时,线程
A
获取互斥体
A
,线程
B
获取互斥体
B
,线程
C
获取互斥体
C
。如果
B
然后等待
a
被释放,而
C
等待
B
a
等待
C
,我们就实现了死锁。避免这种情况的方法是在设计代码时使用常识。常识只需要很少的资源,但对许多资源来说,你必须组织起来。画一两张图表。不过我从没见过这种。它们很有趣。@Lundin,您的死锁示例与您的说法不符,“死锁只是当多个线程等待同一资源时。”当线程等待同一事物时,我们称之为“争用”,这并不总是一件坏事。另一方面,死锁的名称中有“dead”是有充分理由的。@Lundin即使使用“常识”也会使避免死锁变得过于复杂。避免死锁很简单——总是以相同的顺序获取锁。时期并且永远不要升级锁-例如将只读锁转换为写锁。在我看来,如果您不能指定并强制执行特定的锁定顺序,那么您的设计就太复杂了,不可能可靠——我的意思是,在所有方面都不可靠,而不仅仅是在避免死锁方面。