【问题标题】:"Un-casting" from (void *) and de-referencing to char array从 (void *) 中“取消转换”并取消对 char 数组的引用
【发布时间】:2013-02-27 08:41:58
【问题描述】:

我几乎完成了一项要求我使用 pthread 的家庭作业。我已经弄清楚了pthreads。我剩下的唯一问题是弄清楚如何通过 pthread_create() 将多个参数传递给线程。

我需要将两个字符传递给线程。我必须将它们转换为 (*void) 才能与 pthread_create() 一起使用。我可以传递它们,但我不知道如何从函数中的 *parameter 获取值。

void *my_function(void *parameter) {

    /* ATTEMPT 1 - DOESN'T WORK */
    //char* arguments[2];
    //arguments = (char * [2]) parameter;
    /*Error message: 
    error: ISO C++ forbids casting to an array type char* [2] [-fpermissive]
    error: incompatible types in assignment of char** to char*[2]
    */

    /* ATTEMPT 2 - DOESN'T WORK */
    //char *my_data = (char *)parameter;
    //my_data is blank when I try to use cout to check it's values

    /* What I need to do is get those two chars from the array and print them out as part of this thread function */

    pthread_exit(NULL);
}

int main(int argc, char **argv) {

    char duration = '5'; //in reality, this value is taken from argv but I am leaving that out for brevity

    pthread_t threads[3];

    for(int i=0; i < 3; i++){

         char thread_args[2] = {i, duration};

         //create thread with arguments passed in
         int results = pthread_create(&threads[i], NULL, my_function, (void *) &thread_args);

         //testing for pthread error
         if (results){
             printf("ERROR; return code from pthread_create() is %d\n", results);
             exit(-1);
         }

     }

    /* Wait for all threads to complete */
    for (int j=0; j < num_threads; j++) { // https://computing.llnl.gov/tutorials/pthreads/
        pthread_join(threads[j], NULL);
    }


    /* some information prints here that is unrelated to my problem (the date, time, etc) */

    pthread_exit(NULL);
}

我能够毫无问题地传递一个值。有什么建议吗?

我能找到的最接近的现有问题是这个,但我仍然没有运气:Converting from void* to char ** in C

谢谢!

【问题讨论】:

  • 用这两个字符创建一个数组或结构,并传递一个指向任一字符的指针。
  • @Code-Guru: thread_args 似乎已经是一个包含两个字符的数组。
  • @kelseyelayne:你知道'\1''1'的区别吗?
  • 非常感谢您的帮助。

标签: c++ pointers casting pthreads void-pointers


【解决方案1】:

注意在这个循环中:

for(int i=0; i < 3; i++){
    char thread_args[2] = {i, duration};
    int results = pthread_create(&threads[i], NULL, my_function, (void *) 
    ...
}

thread_args 是一个具有自动存储持续时间的本地数组,其生命周期与每次迭代相关,因此您存储这些参数的内存可能会在线程访问它之前被释放,这将导致未定义的行为在这种情况下。

更好的方法是创建一个结构,用于将数据传递给该线程:

typedef struct {
    char duration;
    int num;
} ThreadData;

那么您的代码可能如下所示:

void *my_function(void *parameter) {
    // retrieve and print the thread data:
    ThreadData* td = (ThreadData*) parameter;
    printf("num = %d, duration = %c\n", td->num, td->duration);
    delete td;
    return NULL;
}

int main(int argc, char **argv) {
    char duration = '5';
    pthread_t threads[3];

    for (int i = 0; i < 3; i++) {
        // create structure that will be passed to thread:
        ThreadData* td = new ThreadData;
        td->duration = duration;
        td->num = i;

        //create thread with arguments passed in:
        int ret = pthread_create(&threads[i], NULL, my_function, (void *) td);

        //testing for pthread error:
        if (ret) {
            printf("ERROR; return code from pthread_create() is %d\n", ret);
            exit(-1);
        }
    }
    // wait for all threads to complete:
    for (int i = 0; i < 3; i++) {
        pthread_join(threads[i], NULL);
    }
    exit(0);
}

还要注意,要结束线程的执行,最好使用return 而不是pthread_exit,因为使用return 可以保证线程例程中的变量将被销毁并且堆栈将被展开。欲了解更多信息,请参阅return() versus pthread_exit() in pthread start functions

【讨论】:

  • 虽然td = static_cast&lt;ThreadData*&gt;(parameter) 可能比 C 风格的演员 (td = (ThreadData*) parameter;) 更合理。
猜你喜欢
  • 2021-12-03
  • 2019-05-23
  • 1970-01-01
  • 2014-04-29
  • 2012-09-09
  • 2015-10-05
  • 1970-01-01
  • 2011-10-20
  • 1970-01-01
相关资源
最近更新 更多