代码之家  ›  专栏  ›  技术社区  ›  claf

C:pthread dataspecific是如何工作的?

  •  4
  • claf  · 技术社区  · 16 年前

    static pthread_key_t key;
    static pthread_once_t key_once = PTHREAD_ONCE_INIT;
    
    static void
    make_key()
    {
      (void) pthread_key_create(&key, NULL);
    }
    
    func()
    {
      void *ptr;
    
      (void) pthread_once(&key_once, make_key);
      if ((ptr = pthread_getspecific(key)) == NULL) {
        ptr = malloc(OBJECT_SIZE);
        ...
        (void) pthread_setspecific(key, ptr);
      }
      ...
    }
    

    如果您能解释一下dataspecific是如何工作的,以及它是如何在pthread(简单方式)中实现的,我们将不胜感激!

    2 回复  |  直到 7 年前
        1
  •  7
  •   paxdiablo    15 年前

    密钥在所有线程之间共享,因为它是用 pthread_once() 第一次需要时,但为该键指定的值对于每个线程都是不同的(除非它仍然设置为NULL)。通过具有值a void*

    我使用它们的一个方面是使标准C库线程安全。这个 strtok() 函数(与线程安全相反 strtok_r() 在我参与的一个实现中,我第一次调用它时使用了几乎完全相同的代码,来分配一些内存供 用于存储后续呼叫的信息。这些后续调用将检索特定于线程的数据,以继续标记字符串,而不会干扰其他线程执行完全相同的操作。

    这意味着库的用户不必担心线程之间的串扰——他们仍然需要确保一个线程在最后一个线程完成之前不会调用函数,但这与单线程代码相同。

    它允许我们为系统中运行的每个线程提供一个“合适的”C环境,而不受其他供应商强加给其用户的通常“您必须调用这些特殊的非标准重入例程”的限制。

    至于实现,根据我对DCE用户模式线程(我认为是当前pthreads的前身)的记忆,每个线程都有一个单一的结构,存储指令指针、堆栈指针、寄存器内容等内容。这是一个非常简单的事情,添加一个指向此结构的指针,以最小的成本实现非常强大的功能。指针指向键/指针对的数组(在某些实现中是链表),因此每个线程可以有多个键(例如,一个用于 ,一张 rand() ).

        2
  •  1
  •   HUAGHAGUAH    16 年前

    只要结果是一样的,实现实际上并不重要(每个操作系统可能会有所不同)。

    您可以将其视为两级hashmap。该键指定要访问的线程本地“变量”,第二级可以执行线程id查找以请求每个线程的值。