C 是否在循环中局部声明了一个变量,该循环创建了一个线程,即使在下一次迭代之后也可以在被调用的线程中使用?

C 是否在循环中局部声明了一个变量,该循环创建了一个线程,即使在下一次迭代之后也可以在被调用的线程中使用?,c,scope,memory-management,pthreads,C,Scope,Memory Management,Pthreads,我对C语言中的变量作用域和内存管理有一个问题。我正在编写一个程序,它侦听套接字连接,然后启动一个新线程来处理该客户机。main while()循环可以启动许多单独的线程。我的问题是: 如果我不使用动态内存分配(nomalloc()),而是按如下所示在本地声明一个变量,那么即使在循环的下一次迭代发生之后,在被调用的线程中使用该变量是否安全 while(1) { // Accept new socket connection here // ... pthread_t pt

我对C语言中的变量作用域和内存管理有一个问题。我正在编写一个程序,它侦听套接字连接,然后启动一个新线程来处理该客户机。main while()循环可以启动许多单独的线程。我的问题是:

如果我不使用动态内存分配(no
malloc()
),而是按如下所示在本地声明一个变量,那么即使在循环的下一次迭代发生之后,在被调用的线程中使用该变量是否安全

while(1)
{
    // Accept new socket connection here
    // ...

    pthread_t pt;
    struct mypthreadargs args;

    rc = pthread_create(&pt, NULL, handle_client, &args);
    // The handle_client() function makes extensive use of the 'args' variable
}
创建线程后,
args
变量(和
pt
变量)会发生什么变化?当while()循环重新开始时,内存是否会丢失,或者使用它们是否安全


谢谢

每次迭代完成后,您就失去了对
pt
args
的所有权。访问它们是未定义的行为

要处理注释,您可以在循环外部定义这两种类型的数组,或使它们成为全局数组:

pthread_t pt[...];
struct mypthreadargs args[...];
while(1)
{
...
}

当然,您必须确保在线程完成之前不会离开该范围。

一旦每次迭代完成,您就失去了对
pt
args
的所有权。访问它们是未定义的行为

要处理注释,您可以在循环外部定义这两种类型的数组,或使它们成为全局数组:

pthread_t pt[...];
struct mypthreadargs args[...];
while(1)
{
...
}

当然,您必须确保在线程完成之前不会离开该作用域。

不,您不想这样做

它可能工作,也可能不工作,具体取决于如何调用这一切——实际上,在大多数体系结构上,在大多数编译器中,&args指向的内存将继续有效,但很可能最终会有多个线程使用相同的myptreadargs结构,这可能是您不想要的(实际行为尚未定义,这只是一种可能的结果)

相反,
malloc()
struct mypthreadargs


如果你真的想解决这个问题,并且你愿意同时使用最多数量的线程,那么你可以设置一个args结构数组,并在每次迭代中使用一个新的args结构,并在调用线程完成后将它们标记为可用。在这一点上,你基本上是在重新实现一个有限的
malloc()
,但是,我怀疑这个练习是否明智。

不,你不想这样做

它可能工作,也可能不工作,具体取决于如何调用这一切——实际上,在大多数体系结构上,在大多数编译器中,&args指向的内存将继续有效,但很可能最终会有多个线程使用相同的myptreadargs结构,这可能是您不想要的(实际行为尚未定义,这只是一种可能的结果)

相反,
malloc()
struct mypthreadargs


如果你真的想解决这个问题,并且你愿意同时使用最多数量的线程,那么你可以设置一个args结构数组,并在每次迭代中使用一个新的args结构,并在调用线程完成后将它们标记为可用。在这一点上,你基本上是在重新实现一个有限的
malloc()
,但是,我怀疑这个练习是否明智。

这是非常不安全的。一旦创建了线程并执行了下一个循环,那么mpthreadargs可能会填充下一次迭代的数据,而不是预期传递给线程的数据

如果不想使用堆分配,则需要在比线程寿命更长的作用域中创建变量。例如,在全局作用域中创建一个mpthreadargs对象数组,其大小为所需的线程数。如果不知道线程的最大大小,则必须使用堆分配


你为什么反对使用malloc?

这是非常不安全的。一旦创建了线程并执行了下一个循环,那么mpthreadargs很可能会填充下一次迭代的数据,而不是预期传递给线程的数据

如果不想使用堆分配,则需要在比线程寿命更长的作用域中创建变量。例如,在全局作用域中创建一个mpthreadargs对象数组,其大小为所需的线程数。如果不知道线程的最大大小,则必须使用堆分配


您为什么反对使用malloc?

当您将某些数据的地址传递给线程时,该数据的生存期与父线程的执行无关,因此您唯一的真正选择是以将其生存期与父线程的执行分离的方式为该数据分配内存,即使用somethin进行分配g如malloc或calloc。

当您将某些数据的地址传递给线程时,该数据的生存期与父线程的执行无关,因此您唯一真正的选择是以将其生存期与父线程的执行分离的方式为该数据分配内存,即使用类似malloc或calloc的内容进行分配

除了使用malloc()之外,还有其他解决方法吗?如果可以的话,我想保留堆栈上的变量。@Tom:为什么?堆栈不是线程之间传递数据的合适位置。创建一个结构数组,每个线程在该数组中都有自己的条目。在函数返回之前,请确保
等待
每个线程完成。是否有其他方法解决这个问题n使用malloc()?如果可以的话,我想保留堆栈上的变量。@汤姆:为什么?堆栈不是线程之间传递数据的合适位置。创建一个结构数组,每个线程在该数组中都有自己的条目。在该函数返回之前,请确保