在pthread create中传递的struct参数被破坏

时间:2013-02-03 08:10:55

标签: c multithreading gnu

我有一个名为command的结构,看起来像这样。枚举中的第一个值是AND_COMMAND

struct command
{
  enum command_type type;
  int status;
  char *input;
  char *output;
  union
  {
    struct command *command[2];
    char **word;
    struct command *subshell_command;
  } u;
};

当我调用pthread_create时,我以command_t的形式传递一个命令(转换为(void *))。

typedef struct command *command_t;

我的线程接受this(void *)command_t,将其强制转换(command_t)并尝试使用该结构。

void execute_thread(void *c) {
  command_t command = (command_t) c;

然而,当我将struct传递给execute_thread时,第一个值被清零。如果我的命令类型为SIMPLE_COMMAND且状态为-1,则当它传入线程时,command_type为AND_COMMAND且状态为0.但结构中的其他值均未更改。什么是更奇怪的是这种数据错误发生时。我能够在gdb中捕获这种现象:

445   command_t command = (command_t) c;
(gdb) p *((command_t) c)
$6 = {type = SIMPLE_COMMAND, status = -1, input = 0x605370 "abc", output = 0x605390 "def", u = {
command = {0x6052e0, 0x0}, word = 0x6052e0, subshell_command = 0x6052e0}}
(gdb) n
(gdb) p *((command_t) c)
$7 = {type = AND_COMMAND, status = 0, input = 0x605370 "abc", output = 0x605390 "def", u = {command = {
  0x6052e0, 0x0}, word = 0x6052e0, subshell_command = 0x6052e0}}

看来c指向的结构在用(command_t) c;投射之前不会改变。我完全被这种行为所困扰。我不认为投射指针可能会改变它指向的值。有人可以指出,哈哈,这可能会发生什么?我非常感激。

1 个答案:

答案 0 :(得分:2)

  

更奇怪的是,这种数据错误发生时。我能够在gdb中捕获这种现象:

这里的措辞让我相信这个问题不是确定性的;即,有时它不会发生,或者在您碰巧在问题中的gdb中捕获时不会发生。

如果是这种情况(也许即使不是这样),我怀疑你的问题是你在主线程中分配给struct command的内存(或任何线程正在创建execute_thread()线程)。您没有向我们展示线程创建代码,但是如果您使用局部变量并将其地址传递给创建的线程,那么确保局部变量的生命周期在第二个线程之前不会过期可能会很棘手开始使用它。您可能希望传入已在堆上分配的struct command

struct command* thread_data = malloc(sizeof(struct command));
struct_command_init(thread_data);

pthread_create(/* ... */, thread_data);
// ...

并在execute_command()帖子中:

void* execute_command(void* p)
{
    struct command cmd = *(struct command*)p;
    free(p);

    // use cmd to get at the structure data passed in...
}

请记住,各种指针引用的数据struct command也需要明确管理其生命周期和所有权。