Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.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中无锁列表的标记指针_C++_Pointers_Bitmask_Lock Free - Fatal编程技术网

C++ C中无锁列表的标记指针

C++ C中无锁列表的标记指针,c++,pointers,bitmask,lock-free,C++,Pointers,Bitmask,Lock Free,我试图使用标记指针来处理列表上的无锁操作,以阻止比较和交换(CAS)在该事务期间,如果其他线程在列表上操作,则无法通过。我的节点结构和CAS如下所示: struct node { unsigned long key; unsigned long val; struct node * next; }; static inline bool CAS(std::atomic<node*> node, struct node* oldNode, struct nod

我试图使用标记指针来处理列表上的无锁操作,以阻止比较和交换(CAS)在该事务期间,如果其他线程在列表上操作,则无法通过。我的节点结构和CAS如下所示:

struct node {
    unsigned long key;
    unsigned long val;
    struct node * next;
};

static inline bool CAS(std::atomic<node*> node, struct node* oldNode, struct node* newNode)
{
    node.compare_exchange_strong(oldNode, newNode, std::memory_order_seq_cst);
}
因此,我不清楚的是,例如在setTagMask中,如果我在列表中使用它,它将删除对其值和下一个元素的所有引用


有人能解释一下我如何正确设置这些位,使列表中的其他元素保持不变吗

函数返回指针的修改版本
p
。如果将此修改后的指针存储在链接列表中,则列表将被破坏,因为修改后的指针不再指向
节点

指针修改如下。指针
p
被转换为能够存储指针的无符号整数:。 然后根据
掩码\u位设置一个或多个位。最后,将结果转换回指针并返回

函数
isMaskFlagSet
检查掩码位是否仍然设置


我能想象的唯一用例是:在使用指针之前,每次都必须调用
isMaskFlagSet
。如果设置了掩码位,则禁止实际使用指针。

但实际上我想做的是,根据某些场景修改一个或两个位,这样我就可以知道是否在不同线程中的这些节点上执行了任何操作。此外,如果节点上有另一个线程工作,这将阻止CAS,因为由于这些位,预期值和实际值将不匹配。然后,您必须扩展
struct节点
,以包含此类位字段,例如“请勿触摸字段”。然后该字段应使用CAS进行修改。你不应该修改指针。@MartinZabel我想他指的是其他东西:他想在指针地址中设置未使用的位,以便CAS两个节点指针。事实上,如何做到这一点?我也面临同样的问题。@Tamasinout也许我不明白。您不能依赖指针中未使用的位。这完全依赖于实现/平台。在x86/x64体系结构上,您有一些未使用的位(如果我没记错的话,在x64上有3个未使用的位或x86和5个未使用的位)。这是更广泛的描述:。因此,我确实在承担一些特定于平台的风险,因为我将以x86/x64为目标。但我仍然无法正确设置指针地址位,也无法正确设置OP。
__inline struct node* setTagMask(struct node* p, int MASK_BIT)
{
    return (struct node*) ((uintptr_t)p | MASK_BIT);
}

__inline bool isMaskFlagSet(struct node* p)
{
    return ((uintptr_t)p & MASK_BIT) != 0;
}