线程是否共享局部变量?

时间:2017-01-13 10:11:17

标签: multithreading operating-system

我正在阅读Silberschatz第7版的操作系统概念,它说同一进程的线程共享代码部分,数据部分和其他O.S.资源,但有不同的堆栈和寄存器集。但是,问题集我正在研究线程共享局部变量的状态,但不是存储在堆栈上的局部变量,所以各个线程应该有自己的副本?

5 个答案:

答案 0 :(得分:15)

Threads通常会分享以下内容。

  1. 数据段(全局变量,静态数据)
  2. 地址空间。
  3. 代码段。
  4. I / O,如果文件打开,所有线程都可以读/写它。
  5. 父级的进程ID。
  6. The Heap
  7. threads维护自己的stack副本,并且局部变量存储在堆栈中,所以你是对的每个线程应该有自己的局部变量副本。

    可能是一个不好用的术语,也可能是问题集特有的东西。

答案 1 :(得分:1)

我读到单个进程可以有多个线程。 同一进程的多个线程确实在它们之间共享内容。如果您想知道它们共享的内容和不共享的内容。考虑进程由地址空间,堆栈,堆,全局变量,代码,数据,OS资源组成,它们之间由线程共享?我有以下猜测:

  

全局变量 - 我读过线程共享全局变量。在使用Java和C#进行编程时,我已经创建了共享类的线程   级别变量。所以我相信线程共享全局   变量(虽然不确定是否在高级别的概念   编程语言转换为低操作系统级别   事实)。

     

- 由于全局变量存储在堆中,因此堆在线程之间共享。

     

堆栈 - 由于每个线程都有自己的执行序列/代码,因此它必须有自己的堆栈,它可能会推送/弹出   它的程序计数器内容(当说函数调用并返回时)   发生)。因此,相同进程的线程不共享堆栈。现在我   不确定分享以下事情

     

地址空间 - 不确定地址空间下的确切位置。但我猜地址空间通常用于上下文中   进程,而不是线程。并且因为相同进程的所有线程都存在   在与父进程相同的地址空间中,可以说是这样   大段引用   线程共享地址空间。 (但后来他们保持不同的筹码   在同一地址空间内?)

     

操作系统资源 - 我想这可能是特定于实现的。例如,父进程可以选择性地给出相同文件的句柄   一些线程,而不是所有。或者我错了和OS资源   是指文件以外的东西吗?

     

代码 - 线程可以有不同的代码,因此共享代码并非总是如此。

     

数据 - 不确定在数据下要考虑什么。但是确保全局变量在线程之间共享。当然   变量没有类似的共享。总的来说,我很困惑   由于含糊不清的术语,在操作中完成了超级概括   提供系统书籍和额外实施的具体细节   线上。所以我试图找到一些能让我满意的答案。

所以我得出结论,线程维护自己的堆栈,并且局部变量存储在堆栈中,因此可能无法在线程中共享局部变量。

答案 2 :(得分:1)

符合POSIX标准的操作系统'线程必须共享局部变量(a.k.a。自动变量)。来自卷XBD,基本定义,第3章,定义,条目3.404,Open Group Base Specifications Issue 7的主题(在回答时):

  

任何其地址可由线程确定的东西,包括但不限于静态变量,通过malloc()获得的存储,通过实现定义的函数获得的直接可寻址存储,以及自动变量,都可以被同一个线程访问过程

如果假设静态变量确实在线程之间共享,那么带有输出10的以下代码应足以举例说明我的声明:

#include <pthread.h>
#include <unistd.h>
#include <stdio.h>

static int* shared_pointer = NULL;

void* alter_thread_entry(void* arg) {
    // The following variable will be reachable,
    // while it exists, by both the main and the alter thread.
    int local_variable = 10;
    shared_pointer = &local_variable;
    sleep(2);
    return 0;
}

int main() {
    pthread_t alter_thread;
    pthread_create(&alter_thread, NULL, alter_thread_entry, NULL);
    sleep(1);
    printf("%i", *shared_pointer);
    fflush(stdout);
    pthread_join(alter_thread, NULL);
}

跟踪线程控制执行的调用堆栈是进程线程之间不共享的内容。但是,这一点与实现有关,因为在上述标准中没有建立任何关于它的内容。

答案 3 :(得分:0)

进程中的线程共享相同的地址空间。

A&#34;变量&#34;是一种编程语言概念。当源代码通过编译器时,变量会消失(有些可能会缩减为符号)。

线程可以共享所有内存。一个线程可以访问另一个线程的任何内存位置。

完成此操作的难易程度取决于编程语言和底层链接器支持。很少有编程语言具有真正的线程支持(例如,Ada称为文本)。 Ada有明确的机制允许线程使用变量共享数据。

那么:

  

我正在阅读Silberschatz第7版的操作系统概念,

这是你问题的开始。

  

它表示同一进程的线程共享代码段,数据段和其他O.S.资源,

有所有系统特定的概念。在许多系统中,没有A&#34;代码部分&#34;和A&#34;数据部分。&#34;存在具有特定属性的简单存储器(例如,只读,读/写,读/执行)。

  

但具有单独的堆栈和寄存器集。

寄存器是在调度线程时分配的系统资源。线程没有自己的寄存器集。每个线程都有自己独特的寄存器值集,这些寄存器值在线程处于活动状态时加载,并在线程处于非活动状态时保存。

堆栈只是读/写内存块。

  

然而,问题集我正在研究线程共享局部变量但是不是存储在堆栈上的局部变量,所以各个线程应该有自己的副本吗?

同样,线程共享内存。他们分享&#34; local&#34;变量仅在所使用的编程语言支持这种共享时才发生,或者这种共享发生在&#34;意外。&#34;

变量到内存分配类型使用的映射是编译器的一个功能。 FORTRAN 66/77和COBOL通常不会在堆栈上分配任何变量

答案 4 :(得分:0)

我将尝试用简单的词来解释。注意三件事

堆栈

堆--GLOBAL变量

代码段-代码和一些静态变量

现在我要来堆积

每个线程都有自己的堆栈,线程在执行后释放其堆栈。而且堆栈是线程专有的,这意味着除了其所有者线程之外没有人可以访问它。

因此局部变量以及主线程和另一个线程的堆栈中的局部变量将具有自己的堆栈,因此线程不可能共享局部变量。

希望有帮助。