引用或复制结构的结构(已分配的memset)是一件有效的事情

is referencing or copying a struct of a struct (memset allocated) a valid thing to do?

本文关键字:结构 一件 有效 memset 复制 分配 引用      更新时间:2023-10-16

为了在线程(pthread)中使用网络信息(udp-sockaddr_In和套接字编号),我在主函数中设置了udp-socket,然后我想创建一个结构,其中包含((sockaddr_In),它是一个结构和(int socket))作为pthread_create函数的参数。

将结构从main中创建的套接字复制到全局函数(用于线程)中是一件危险的事情吗?因为它是在堆栈之外分配的,或者引用它会更好

我想做的是:

rc = pthread_create(&thread1, NULL, myfunction, (void *) &StructArg);

其中thread1是我想要使用(void)myfunction(voidStructArg)的位置

假设(sockaddr_in-Addrem)在被memset 后已经被填充

struct NetworkInfo { sockaddr_in remote ; int socket ;} ;
NetworkInfo NI;
NI.remote= Addrem;
NI.socket=sock;  // from socket(sock,.....)

或者有更好的方法吗

我衷心感谢您的投入。

非常感谢

这取决于结构的分配位置。您必须确保结构在线程结束之前一直保留在内存中。如果结构被声明为调用pthread_create()的函数的局部变量,这是危险的,例如:

void somefunc()
{
    struct NetworkInfo NI;
    // fill NI as needed...
    rc = pthread_create(&thread1, NULL, &myfunction, &NI);
}

除非您在线程上加入相同的函数以等待它终止:

void somefunc()
{
    struct NetworkInfo NI;
    // fill NI as needed...
    rc = pthread_create(&thread1, NULL, &myfunction, &NI);
    // ...
    pthread_join(thread1, ...);
}

否则,您将不得不将结构声明为全局变量(并且永远不要创建同时使用它的多个线程):

struct NetworkInfo NI;
void* myfunction(void *arg)
{
    // use NI as needed...
    return ...;
}
void somefunc()
{
    rc = pthread_create(&thread1, NULL, &myfunction, NULL);
}

或者在堆上分配结构,并在使用它时让线程释放它:

void* myfunction(void *arg)
{
    struct NetworkInfo *NI = (struct NetworkInfo*) arg;
    // use NI as needed...
    free(NI);
    return ...;
}
void somefunc()
{
    struct NetworkInfo *NI = malloc(sizeof(struct NetworkInfo));
    // fill NI as needed...
    rc = pthread_create(&thread1, NULL, &myfunction, NI);
}

或者:

#include <memory>
void* myfunction(void *arg)
{
    std::auto_ptr<struct NetworkInfo> NI( (struct NetworkInfo*) arg );
    // use NI as needed...
    return ...;
}
void somefunc()
{
    std::auto_ptr<struct NetworkInfo> NI(new struct NetworkInfo);
    // fill NI as needed...
    rc = pthread_create(&thread1, NULL, &myfunction, NI.get());
    NI.release();
}