2017-01-13 133 views
5

我正在阅读Silberschatz第7版的Operating System Concepts,它说同一进程的线程共享代码段,数据段和其他O.S.资源,但具有单独的堆栈和寄存器组。但是,我正在处理的问题集表明线程共享局部变量,但不是存储在堆栈中的局部变量,因此各个线程应该有自己的副本?线程是否共享局部变量?

+0

'问题集'可能是错误的或使用不好的术语,很难说。你能发表有意义的报价吗? –

+0

但是:不,线程不共享真正的本地变量。但是在C#中,一个局部变量可能会被捕获或“关闭”,然后它变成另一个故事。 –

回答

7

Threads通常共享以下内容。

  1. 数据段(全局变量,静态数据)
  2. 地址空间。
  3. 代码段。
  4. I/O,如果文件处于打开状态,所有线程都可以读取/写入。
  5. 父进程ID。
  6. 的堆

threads维护自己的stack副本,局部变量都存储在堆栈上这样啊,你是正确的,每个线程都应该有自己的局部变量的副本。

可能是它使用的一个不好的术语,也可能是它的特定问题集。

+0

Silberschatz使用的术语当然是由该地区的专业人士修改的。几乎不好。 –

1

我读过单个进程可以有多个线程。 同一进程的多个线程在它们之间共享事物。如果你想知道他们分享什么,不知道什么。考虑到进程由地址空间,堆栈,堆,全局变量,代码,数据,OS资源组成,它们之间由线程共享的是什么?我有以下猜测:

全局变量 - 我已阅读线程共享全局变量。同时,在Java和C#编程时,我已经创建线程来共享 级别的变量。所以我相信这些线程共享全局变量(虽然不确定高级编程语言中的概念是否转化为低操作系统级别的事实)。

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

堆栈 - 因为每个线程都可以有自己的执行顺序/代码,就必须有自己的堆栈,它可能会推/流行 其程序计数器的内容(当说函数调用和返回 发生)。所以同一进程的线程不共享堆栈。现在我 不确定以下事情的共享

地址空间 - 不知道地址空间下的究竟是什么。但我猜想地址空间通常用于 进程的上下文中,而不是线程。并且因为所有相同进程的线程都驻留在与父进程相同的地址空间中,所以 块引用 线程共享地址空间。 (但是,他们在同一地址空间内维护不同的堆栈 ?)

操作系统资源 - 我想这可能是非常具体的实现。例如,父进程可以选择性地将相同文件的句柄赋给 的一些线程,而不是全部。或者我错了,操作系统资源 意味着文件以外的东西?

代码 - 线程可以有不同的代码,所以共享代码并不总是这种情况。

数据 - 不确定在数据下需要考虑什么。但确保全局变量在线程间共享。并确保本地 变量没有类似的共享。总的来说,我很困惑 由于含糊不清的条款,在操作 完成的超级概括在线提供的系统书籍和额外实施细节 。所以我想找到一些可以满足我的答案。

所以我来得出这样的结论,线程维护自己的堆栈,和局部变量都存储在堆栈上,所以可能在线程局部变量是不可能的共享。

0

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

“变量”是一种编程语言的概念。当源代码通过编译器时,变量消失(有些可能会减少为符号)。

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

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

那么接下来:

我被Silberschatz 7版阅读操作系统的概念,

那是你的问题的开始。

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

有所有系统特定的概念。在许多系统中,不存在“代码段”和“数据段”。只有具有特定属性的内存(例如,只读,读/写,读/执行)。

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

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

堆栈只是读/写内存块。

但是,我正在处理的问题集表示线程共享局部变量,但不是存储在堆栈上的局部变量,因此各个线程应该有自己的副本?

同样,线程共享内存。只有当使用的编程语言支持这种共享或者这种共享是由“事故”发生时,它们才共享“本地”变量。

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

0

符合POSIX标准的OS的线程必须共享局部变量(又名自动变量)。从卷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); 
} 

调用堆栈该迹线的控制执行线程是一个进程的线程之间不共享的线程。然而,这一点是依赖于实现的,因为在前述标准中没有确定它。