Multithreading 线程共享局部变量吗?

Multithreading 线程共享局部变量吗?,multithreading,operating-system,Multithreading,Operating System,我正在阅读Silberschatz第七版的《操作系统概念》,它说同一进程的线程共享代码段、数据段和其他O.S.资源,但有单独的堆栈和寄存器集。然而,我正在处理的问题集表明线程共享局部变量,但不是存储在堆栈上的局部变量,所以单个线程应该有自己的副本 线程通常共享以下内容 数据段(全局变量、静态数据) 地址空间 代码段 I/O,若文件是打开的,所有线程都可以读/写它 父进程的进程id 堆 但是线程维护它们自己的堆栈副本,局部变量存储在堆栈上,因此您是对的,每个线程都应该有自己的局部变量副本。 可能是

我正在阅读Silberschatz第七版的《操作系统概念》,它说同一进程的线程共享代码段、数据段和其他O.S.资源,但有单独的堆栈和寄存器集。然而,我正在处理的问题集表明线程共享局部变量,但不是存储在堆栈上的局部变量,所以单个线程应该有自己的副本

线程通常共享以下内容

  • 数据段(全局变量、静态数据)
  • 地址空间
  • 代码段
  • I/O,若文件是打开的,所有线程都可以读/写它
  • 父进程的进程id
  • 但是
    线程
    维护它们自己的
    堆栈副本
    ,局部变量存储在堆栈上,因此您是对的,每个线程都应该有自己的局部变量副本。


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

    我了解到单个进程可以有多个线程同一进程的多个线程之间确实共享内容。如果您想知道它们共享什么,不共享什么。考虑到进程由地址空间、堆栈、堆、全局变量、代码、数据、操作系统资源组成,线程共享其中哪些资源?我有以下猜测:

    全局变量-我已读取线程共享全局变量。在用Java和C#编程时,我还制作了线程来共享类 级别变量。所以我相信这些线程共享全局 变量(但不确定概念是否处于高级 编程语言按原样转换为低操作系统级别 事实)

    -由于全局变量存储在堆中,所以堆在线程之间共享

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

    地址空间-不确定地址空间下的确切数字。但我猜地址空间通常用于 进程,而不是线程。由于同一进程的所有线程都驻留在 在与父进程相同的地址空间中,据说 块引用 线程共享地址空间。(但它们保持不同的堆栈 在同一地址空间内?)

    操作系统资源-我想这可能是非常具体的实现。例如,父进程可以选择性地将同一文件的句柄赋予 它的一些线程,而不是所有线程。或者我误解了操作系统资源 是指文件以外的东西吗

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

    <强>数据< /强> -不确定数据下该考虑什么。但要确保全局变量在线程之间共享。而且当地的 变量不是类似地共享的。总的来说,我相当困惑 由于术语模糊,在操作系统中进行了超概括 提供了系统手册和额外的具体实施细节 在线 的所以我在努力寻找一些能让我满意的答案


    因此我得出结论,线程维护自己的堆栈,局部变量存储在堆栈上,因此可能无法在线程中共享局部变量。进程中的线程共享相同的地址空间

    “变量”是一种编程语言概念。当源代码经过编译器时,变量就会消失(有些可能会被简化为符号)

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

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

    那么:

    我在读Silberschatz第七版的《操作系统概念》

    这就是你问题的开始

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

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

    但是有独立的堆栈和寄存器集

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

    堆栈只是读/写内存块

    然而,我正在处理的问题集表明线程共享局部变量,但不是存储在堆栈上的局部变量,所以单个线程应该有自己的副本

    同样,线程共享内存。只有当所使用的编程语言支持这种共享或这种共享是“偶然”发生时,它们才会共享“局部”变量


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

    符合POSIX的OSs线程必须共享本地变量(也称为自动变量)。从卷XBD,基本定义,第3章,定义,条目3.404,线程(在回答时):

    其地址可由线程确定的任何内容,包括但不限于静态变量、通过malloc()获得的存储、通过implementati获得的直接可寻址存储
    #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);
    }