C 从另一个线程访问主线程的局部变量

C 从另一个线程访问主线程的局部变量,c,multithreading,pthreads,posix,C,Multithreading,Pthreads,Posix,以下是本书中的一个示例程序,作者在其中演示了多线程程序中共享变量的用法: #include "csapp.h" #define N 2 void *thread(void *vargp); char **ptr; /* Global variable */ int main() { int i; pthread_t tid; char *msgs[N] = { "Hello from foo",

以下是本书中的一个示例程序,作者在其中演示了多线程程序中共享变量的用法:

#include "csapp.h"

#define N 2

void *thread(void *vargp);

char **ptr; /* Global variable */

int main()
{
    int i;
    pthread_t tid;
    char *msgs[N] = {
        "Hello from foo",
        "Hello from bar"
    };

    ptr = msgs;
    for (i = 0; i < N; i++)
        Pthread_create(&tid, NULL, thread, (void *)i);
    Pthread_exit(NULL);
}

void *thread(void *vargp)
{
    int myid = (int)vargp;
    static int cnt = 0;
    printf("[%d]: %s (cnt=%d)\n", myid, ptr[myid], ++cnt);
    return NULL;
}
#包括“csapp.h”
#定义n2
void*螺纹(void*vargp);
字符**ptr;/*全局变量*/
int main()
{
int i;
pthread_t tid;
char*msgs[N]={
“foo你好”,
“酒吧里的你好”
};
ptr=msgs;
对于(i=0;i
可以看出,两个线程都访问全局变量
ptr
,该变量指向调用
pthread\u exit
的主线程的局部变量
msgs

现在,根据以下文件:

线程终止后,访问线程的本地(自动)变量的结果是未定义的

那么,上面的代码正确吗

即使主线程调用
pthread\u exit
,从另一个线程访问主线程的局部变量是否合法

即使主线程调用pthread_exit,从另一个线程访问主线程的局部变量是否合法

否。一旦主线程通过
pthread\u exit
完成,任何局部变量的生存期(即自动存储持续时间)都将结束。任何来自另一个线程的进一步访问都是未定义的行为

那么,上面的代码正确吗

否。
msgs
数组是一个局部变量,其生存期在调用
pthread\u exit
后结束。因此,任何通过
ptr
的进一步访问都是未定义的

通常,只要对象的生命周期没有结束,从另一个线程访问一个线程的局部变量是有效的。这是由以下方面保证的:

[…]其地址可由线程确定的任何内容,包括 但不限于静态变量,通过malloc()获得的存储, 通过定义的实现获得的直接可寻址存储 中的所有线程都可以访问函数和自动变量 同样的过程

另一件需要注意的事情是,如果您已将
msgs[0]
msgs[1]
传递给线程,则这是有效的。因为
msgs[0]
msgs[1]
指向字符串文本,其生存期仅在程序终止时结束(而不仅仅是有指针指向它的线程)

类似地,如果您通过
malloc
(或其朋友)或任何具有静态存储持续时间的对象进行分配,并将其传递给线程函数,则它也是有效的

e、 g

#包括
#包括
void*thread_func(void*arg)
{
char*str=p;
printf(“%s\n”,str);
返回NULL;
}
内部主(空)
{
pthread_t tid;
char*p=“你好”;
pthread_create(&tid,NULL,thread_func,p);
pthread_exit(NULL);
}
这是完全正确的,因为
p
指向一个字符串文本,该文本即使在
main
通过
pthread\u exit
返回后仍然存在


因此,这里需要注意的重要区别是,对另一个线程中变量的访问是否未定义取决于所述对象的生存期,而不仅仅是变量的定义位置。

为什么
main
甚至调用
pthread\u exit
?它应该调用
pthread\u join
,然后您的问题就会得到解决。(1)这是书中的代码。(2) 从主线程调用
pthread\u exit
是完全合法的,并且有这样的用例(例如,如果主线程只想生成其他分离的线程而不需要等待它们完成)。这是合法的,是的。还要注意,它基本上是传递的
i
的值。线程从不解除对指向
main
本地对象的任何引用。因此,您所考虑的问题并不存在。由于多种原因,此代码不应编译。如果你正在从一本提供此类代码的书中学习,请阅读勘误表,如果勘误表不能解决此问题,请丢弃该书。在C语言中,你根本不能保证能够访问另一个线程的自动存储,更不用说不同步或在其生命周期结束后。该行为未定义。
#include<stdio.h>
#include<pthread.h>

void *thread_func(void *arg)
{
    char *str = p;
    printf("%s\n", str);
    return NULL;
}

int main(void)
{
    pthread_t tid;
    char *p = "Hello";
    pthread_create(&tid, NULL, thread_func, p);
    pthread_exit(NULL);
}