C 函数的线程本地存储

C 函数的线程本地存储,c,multithreading,pthreads,queue,C,Multithreading,Pthreads,Queue,我正在编写一个程序,该程序要求在多线程环境中执行队列操作。 我不确定函数的线程本地存储,而不仅仅是全局变量 我试过了 __thread int head,tail; __thread int q[MAX_NODES+2]; __thread void enqueue (int x) { q[tail] = x; tail++; color[x] = GRAY; } __thread int dequeue () { int x = q[head]; head

我正在编写一个程序,该程序要求在多线程环境中执行队列操作。 我不确定函数的线程本地存储,而不仅仅是全局变量 我试过了

__thread int head,tail;
__thread int q[MAX_NODES+2];

__thread void enqueue (int x) {
   q[tail] = x;
   tail++;
   color[x] = GRAY;
  }

__thread int dequeue () {
   int x = q[head];
   head++;
   color[x] = BLACK;
   return x;
   }
我犯了以下错误

fordp.c:71: error: function definition declared '__thread'

fordp.c:77: error: function definition declared '__thread'
我在某个地方读到一个函数已经是线程安全的,除非它使用共享变量,所以我尝试了

__thread int head,tail;
__thread int q[MAX_NODES+2];

void enqueue (int x) {
   q[tail] = x;
   tail++;
   color[x] = GRAY;
   }

 int dequeue () {
   int x = q[head];
   head++;
   color[x] = BLACK;
   return x;
   } 
它编译时并没有出错,但我的执行结果是错误的,暗示队列在多线程平台上不能很好地工作

有人能解释一下这里发生了什么吗


感谢您的帮助

\u线程
建议编译器为每个线程创建一个变量实例

我怀疑这是你想要的队列,它的头和尾线程应该同时运行,因为一个线程所做的修改不会被任何其他线程看到

因此,请不要在此处使用
\uuu thread
,而是保护对全局变量的并发访问,例如使用一个或多个互斥体



供您参考:

我认为您处理问题的方式不对

您的问题是希望将队列对象与函数调用关联(例如,
enqueue

在C语言中,这些对象通常被称为上下文

您所做的是一个全局变量的变体。使用每线程本地存储有助于节省存储空间或实际的每线程资源。事实并非如此

具有线程安全性和正确性的唯一选项是将上下文添加到函数调用中。 我删除了对
color
的引用以简化事情

struct queue {
    unsigned head, tail;
    int q[MAX_NODES+2];
};

void enqueue (struct queue* q, int x) {
    q->q[q->tail++] = x;
}

int dequeue (struct queue* q) {
    int x = q->q[q->head++];
    return x;
} 

注意:您应该对指针和索引执行检查。

至少有一句引用“线程本地存储”的句子适合您的答案^H^H^H^H^H^H建议。无需重复您的答案+注释。在这种情况下,只是工作的错误工具。谢谢回复。请允许我问一个问题。假设我使用不同的线程执行作业的不同部分(需要排队、入队和出队)。我担心的是上面代码的队列*q。由于线程正在执行不同的作业,我希望它们只处理自己的队列副本。我担心的是一个线程的排队和另一个线程的排队。上述代码是否存在这种风险??上述代码是可重入的-将在多个线程上工作,其中每个线程都在不同的队列结构/对象上工作。如果您想要线程安全(单个队列上有许多线程),您需要使用某种锁(临界区或互斥锁)。互斥锁将是队列结构的一部分。有些互斥锁有自旋锁。这意味着锁定将首先尝试X次,以在没有上下文切换的情况下获得锁(等待互斥导致上下文切换)。因此,如果锁被解锁或功能很快存在,那么性能将非常好。有无锁队列之类的东西,但它们有局限性,在大多数情况下不值得付出努力。感谢您的回复。实际上,在我的程序中,不同线程中的队列将完成不同部分的工作。因此,由于他们将做的工作是独立的(我想我不需要互斥),我想为每个线程创建一个变量实例,这样一个线程的变量(例如head,tail)就不会与变量(head,tail)混淆是的,每个线程有一个队列实例,这些队列彼此独立。实际上,对于2个固定线程,我会将两个单独的队列定义为q1和q2。问题是当我必须为n个线程编写程序时。此时,不再将队列单独定义为q1、q2、q3。。。。在程序本身中,我想定义一次队列,并利用线程本地存储的优势在多个线程中解决它。我说的有道理吗@阿比纳沙迪卡里:是的,你描述的需求和方法绝对有道理。但是,您应该在问题中添加此信息,以避免进一步的误解。