简体   繁体   English

pthread_create参数丢失

[英]pthread_create argument is lost

I'm writing a very simple code in which i need to use some threads. 我正在编写一个非常简单的代码,其中需要使用一些线程。 When I create first type of thread i pass argument with pthread_create: 当我创建第一类线程时,我使用pthread_create传递了参数:

 fman thread_arg;
 thread_arg.sd=sda;
 char* split = strtok(buffer, "|");
 thread_arg.wcount=atoi(split);
 split = strtok(NULL,"");
 strcpy(thread_arg.id, split);
 pthread_create(&thread_temp, NULL, registerF, &thread_arg);

And everything works fine, but in function registerF I need to do something like this: 一切正常,但是在函数registerF中,我需要执行以下操作:

wman thread_arg;
thread_arg.sd=foremans_fd[ix];
thread_arg.fmanix=ix;
strcpy(thread_arg.id,tmpr);
pthread_create(&thread_temp, NULL, registerW, &thread_arg);

Those arguments are structures defined by me: 这些参数是我定义的结构:

typedef struct fman
{
    int sd;
    char id[100];
    int wcount;
} fman;

typedef struct wman
{
    int sd;
    int fmanix;
    char id[100];
} wman;

And when I check it by printf("%x, args) I get the same address but values are different inside. Where is my mistake? 当我通过printf(“%x,args)检查它时,我得到了相同的地址,但内部的值不同。我的错误在哪里?

One likely problem is here: 一个可能的问题在这里:

 fman thread_arg;
 [...]
 pthread_create(&thread_temp, NULL, registerF, &thread_arg);

Note that the thread_arg object is located on the stack, and thus will be destroyed (and likely overwritten by other stack variables) when the function it is declared in returns. 请注意,thread_arg对象位于堆栈上,因此在其声明的函数返回时将被破坏(并可能被其他堆栈变量覆盖)。

pthread_create(), on the other hand, launches a thread that will run asynchronously with this function, which means that the thread can (and often will) run after the function you excerpted has returned, which means that by the time the thread dereferences &thread_arg , thread_arg has likely already been destroyed and that pointer is now pointing to some other data that was written into the same stack location later on. 另一方面,pthread_create()启动一个线程,该线程将与此函数异步运行,这意味着该线程可以(并且通常会) 您摘录的函数返回运行,这意味着在该线程取消引用&thread_argthread_arg可能已被破坏,并且该指针现在指向稍后写入同一堆栈位置的其他一些数据。

Unless you are doing something special to make sure that the struct's lifetime is long enough to include all of the spawned thread's accesses to the struct, then the fact that this code ever works is pure luck (ie the scheduler just happened to schedule the thread to run and perform all of its accesses to the struct before the struct was destroyed/overwritten). 除非您执行特殊的操作以确保该结构的生存期足够长,以包括所有派生线程对该结构的访问,否则该代码曾经有效的事实是很幸运的(即,调度程序刚好将线程调度到在销毁/覆盖该结构之前运行并执行对结构的所有访问)。 You definitely can't depend on that. 您绝对不能依靠它。

In order to fix the problem, you need to either allocate the struct on the heap (so that it won't be destroyed when the function returns -- the spawned thread can then free the struct when it is done using it), or use some kind of synchronization mechanism (eg a condition variable) to cause the main thread to block inside your function until the spawned thread has indicated that it is done accessing the struct. 为了解决该问题,您需要在堆上分配结构(以使函数返回时它不会被破坏-生成的线程可以在使用完结构后释放结构),或者使用某种同步机制(例如条件变量)使主线程在函数内部阻塞,直到生成的线程表明已完成对结构的访问为止。

The thread struct in the running thread is treated like a block of memory and accessed using offsets. 运行线程中的线程结构被视为内存块,并使用偏移量进行访问。 Since your fman and wman structs have different orders (4+100+4) vs (4+4+100), it's likely that you're getting right struct but reading from different memory location, given the passed struct to this thread is fman, and it's being accessed as wman. 由于您的fman和wman结构具有不同的顺序(4 + 100 + 4)与(4 + 4 + 100),因此,鉴于传递给该线程的结构是fman,您可能获得了正确的结构,但从不同的内存位置读取,并且正在以wman的身份进行访问。

Try changing them both to same signature, as in, int, int, char* and it should work. 尝试将它们都更改为相同的签名,例如in,int,int,char *,它应该可以工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM