2013-10-15 40 views
6

在多处理器编程的艺术中,p215,作者说在C中,你可以从指针中“偷走”一点,并且使用按位运算符提取一些标志(一个标记)来自单个词的指针。我不知道这是如何完成的,所以一个例子可以帮助我。从一个指针中偷取位

+3

这可能是有用的知道,这通常是不好的做法,除非真的有正当的理由这样做。 – Mysticial

+1

@Mysticial:尽管这是实现动态语言的常用做法。 –

+2

@Mysticial:当你需要对单个单词进行原子操作时,就有了。 –

回答

7

想象一下具有32位指针大小的系统,但只有1GB的内存可用。您只需要30位来寻址整个存储器空间,所以高2位未被使用。您可以将这两位用于您自己的目的 - 例如,按指针类型(堆栈/全局与动态)标记指针。

请注意,作为结果得到的代码大约是非可移植的。您需要非常熟悉代码运行的CPU - 具体来说,当指针的地址发送到地址总线时,您需要知道高位是否被丢弃。

+2

这在基于68000的系统中非常常见,其中地址空间只有24位--32位地址的前8位可以安全地用于各种标志。早在20世纪80年代的原始Mac OS使用这个技巧来锁定,清除和资源标志。 –

7
  1. 确保指针对象在内存中对齐,以便所有的指针都是偶数。最后一位可用于存储单个布尔标志。 (这是不能完全移植的,所以你需要知道该平台。)

  2. 移动指针作为类型为uintptr_t的整数。这些可以很容易被操纵:

    bool get_flag(uintptr_t p) 
    { 
        return p & 1; 
    } 
    
    void *get_pointer(uintptr_t p) 
    { 
        return (void *)(p & (UINTPTR_MAX^1)); 
    } 
    
    uintptr_t set_flag(uintptr_t p, bool value) 
    { 
        return (p & (UINTPTR_MAX^1)) | value; 
    } 
    
+0

在java中如何实现相同? – arunmoezhi

+1

Java是一种保姆语言....保姆不会让你这样做:-P – WhiZTiM

+0

在Java中,AtomicMarkableReference类具有相同的功能(用于同步访问共享对象的意图)。今天的保姆与上个千年不同...... –