【发布时间】:2011-01-31 08:29:07
【问题描述】:
我有一个速度关键的多线程程序,它涉及树结构中的数据。实现如下:
typedef struct
{
// data pertaining to linkages, defining the architecture of the tree
int parent_node;
int child_node[MAX_CHILD_NODES];
int number_of_children;
// data pertaining to info at each node
float interesting_info_A;
char interesting_info_B[STRING_LEN];
long interesting_info_C;
}
node_type;
node_type node[MAX_NUMBER_OF_NODES];
CRITICAL_SECTION node_critsec[MAX_NUMBER_OF_NODES];
程序进入和离开由 node_critsec[] 控制的临界区。因此,当我需要处理节点 n 的interesting_info_A/B/C 时,我进入该节点的临界区(node_critsec[n]),进行处理然后离开。该程序在树周围蜿蜒曲折,沿着与父母和孩子的链接走各种复杂的路径。该程序还将增长树,即添加新节点并相应地修改其他节点的父/子链接(树永远不会缩小)。我尝试确保每个线程一次只锁定一个节点,以避免死锁的风险。但是我有一个问题——如果我要添加一个新节点,那么我可能想要锁定节点的父节点,以便我可以调整它的子节点列表。在没有死锁或两个线程尝试修改同一节点中的数据的情况下让所有这些工作都变得有点像一场噩梦。关于何时以及应该遵循哪些节点来锁定/解锁我应该遵循一些指导原则 - 还是我必须非常聪明并计算出可能发生的事件的每一个排列?
【问题讨论】:
-
你能解释一下你遇到死锁的地方吗?这意味着要么你的图表中有循环(不是树),要么在遍历期间你没有在获取子锁之前放弃父锁,这很容易纠正。
-
据我了解,有些算法会自下而上,而其他算法会自上而下,依此类推。我认为他的意思是他需要在将新节点添加到父节点列表之前将其锁定到新节点,否则另一个线程可能会窃取新节点或出错(状态不一致:parent_node 设置为未列出此节点的节点节点作为子节点)。我不知道这个数据结构是否是最优的,但他认为与这个数据结构同步的需要是正确的。
-
@Tyler McHenry:我现在实际上并没有陷入僵局,尽管我过去曾遇到过。我得到它们的时间总是归结为同时锁定两个不同节点的线程之一。我现在的问题是两个不同的线程正在处理相同的节点数据。
标签: c multithreading data-structures deadlock