简体   繁体   English

使用pthread_create调用类型为“ int argc,char ** argv-> int”的C函数。

[英]Use pthread_create to invoke a C function of the type “int argc, char** argv -> int”

I need to use pthread_create to invoke a C function of type 我需要使用pthread_create来调用类型为C的函数

int main_original(int argc, char** argv)

I have tried something like this: 我已经尝试过这样的事情:

pthread_create(&t, NULL, main_original, NULL);

The compiler gives me a type error 编译器给我一个类型错误

invalid conversion from 'int (*)(int, char**)' to 'void* ( )(void )' 从'int(*)(int,char **)'到'void *( )(void )'的无效转换

So, what is the right way to invoke main_original so that its parameters are well passed? 那么,调用main_original以便正确传递其参数的正确方法是什么?

The function pthread_create is only able to call functions with the following signature: 函数pthread_create仅能够调用具有以下签名的函数:

void *fn(void *)

Even if you did manage to cast a pointer to a function with a different signature and successfully pass it to pthread_create , your program is likely to crash as pthread_create will attempt to set up the stack / registers in a way that follows the platform's calling convention for a function with just one void * argument, which will lead to your function being in an indeterminate state. 即使您确实设法将指针转换为具有不同签名的函数并将其成功传递给pthread_create ,您的程序也可能会崩溃,因为pthread_create会尝试按照平台的调用约定来建立堆栈/寄存器。一个仅带有一个void *参数的函数,这将导致您的函数处于不确定状态。

The way to solve your problem would be to use a wrapper function specifically designed for being called by pthread_create like so: 解决问题的方法是使用专门为pthread_create调用而设计的包装器函数,如下所示:

void *main_original_start_routine(void *arg)
{
    main_original(argc, argv);
    return NULL;
}

However, this may not be enough, unless argc and argv are global variables. 但是,除非argcargv是全局变量,否则这可能还不够。 You may find you also need to somehow pass these values through to this function from the scope in which you call pthread_create . 您可能会发现还需要以某种方式将这些值从调用pthread_create的范围传递到此函数。 This can be done via the void *arg argument to pthread_create , by creating a struct holding the state you need, and passing it around via a casted void pointer: 可以通过创建pthread_createvoid *arg参数来实现,方法是创建一个保存所需状态的结构,然后通过强制转换的void指针将其传递给周围:

struct main_original_context {
    int argc;
    char **argv;
};

void *main_original_start_routine(void *arg)
{
    /* Convert the void pointer back to the struct pointer it
     * really is. */
    struct main_original_context *ctx = arg;
    main_original(ctx->argc, ctx->argv);
    return NULL;
}

int main(int argc, char **argv)
{
    pthread_t t;

    struct main_original_context ctx = {
        argc,
        argv
    };

    /* Pass a pointer to our context struct to the thread routine. */
    pthread_create(&t, NULL, &main_original_start_routine, &ctx);

    pthread_join(&t, NULL);

    return 0;
}

Keep in mind however, that ctx only has a lifetime of the duration of the main function in this case. 但是请记住,在这种情况下ctx仅具有main函数持续时间的生存期。 If the function we create the pthread in does not join with pthread_join before returning (and invalidating the struct used to provide context to the thread), then this would be unsafe. 如果我们在其中创建pthread的函数在返回之前未与pthread_join连接(并使用于向线程提供上下文的结构无效),那么这将是不安全的。 Therefore we would have to use dynamic allocation, and make the thread assume responsibility for freeing any dynamically allocated memory: 因此,我们将不得不使用动态分配,并使线程承担释放任何动态分配的内存的责任:

struct main_original_context {
    int foo;
    int bar;
};

void *foobar_start_routine(void *arg)
{
    struct main_original_context *ctx = arg;
    foobar(ctx->foo, ctx->bar);

    /* Free memory we have been given responsibility for. */
    free(ctx);

    return NULL;
}

void asdf(int foo, int bar)
{
    pthread_t t;

    struct main_original_context *ctx;

    /* Allocate memory. */
    ctx = malloc(sizeof *ctx);

    ctx->foo = foo;
    ctx->bar = bar;

    /* Assume `main_original_start_routine` is now responsible for freeing
     * `ctx`. */
    pthread_create(&t, NULL, &foobar_start_routine, ctx);

    /* Now we can safely leave this scope without `ctx` being lost.  In
     * the real world, `t` should still be joined somewhere, or
     * explicitly created as a "detached" thread. */
}

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

相关问题 函数main中的参数argv(int argc,char * argv []) - The parameter argv in the function main(int argc, char *argv[]) 在 C 中将 int ** 传递给 pthread_create - Passing int ** to pthread_create in C 如何在主函数中实现int argc和char * argv []? - How do I implement int argc and char *argv[] in the main function? 使用main(int argc,char ** argv){}作为函数重写程序 - Rewrite a program with main(int argc,char **argv) {} as a function 在 C 中以编程方式调用 main(int argc, char **argv) - Programmatically calling main(int argc, char **argv) in C 如何将 char* argv[] 传递给 pthread_create? - How to pass char* argv[] to pthread_create? 使用main(int argc,char * argv [])的问题 - Problems using main(int argc,char *argv[]) 是否必须编写int main(int argc,char * argv []),不能使用其他名称而不是argc和* argv []? - Is it compulsory to write int main(int argc, char *argv[]), can't use some other names instead of argc and *argv[]? 定义“int main (void)”和“int main (int argc, char *argv[])”有什么区别,什么时候使用? - What is the difference between the definitions “int main (void)” and “int main (int argc, char *argv[])” and when to use which? 在pthread_create()中,将int类型转换为void *是什么意思? - What does int type convert to void* mean in pthread_create()?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM