【问题标题】:how can I pass an local variable from a thread to another thread by accessing its memory address?如何通过访问其内存地址将局部变量从一个线程传递到另一个线程?
【发布时间】:2021-07-26 03:46:31
【问题描述】:

我试图通过从其内存地址访问数组中的值来覆盖数组中下一项的值,该值作为函数 TaskCode 中的参数。我尝试了很多组合,但都没有达到我的预期。

    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <assert.h>
    
    #define NUM_THREADS 5
    
    void* TaskCode(void* argument) {
        int tid = *((int*)argument); //set tid to value of thread
        tid++;  // go to next memory address of thread_args
        tid = *((int*)argument); // set that value to the value of argument
        printf("\nI have the value: \" %d \" and address: %p! \n", tid, &tid);
        return NULL;
    }
    
    int main(int argc, char* argv[]) 
    {
        pthread_t threads[NUM_THREADS]; // array of 5 threads
        int thread_args[NUM_THREADS +1 ];   // array of 6 integers
        int rc, i;
    
            for (i = 0; i < NUM_THREADS; ++i) {/* create all threads */
                thread_args[i] = i; // set the value thread_args[i] to 0,1...,4
                printf("In main: creating thread %d\n", i);
                rc = pthread_create(&threads[i], NULL, TaskCode,
                    (void*)&thread_args[i]);
                assert(0 == rc);
            }
        /* wait for all threads to complete */
        for (i = 0; i < NUM_THREADS; ++i) {
            rc = pthread_join(threads[i], NULL);
            assert(0 == rc);
        }
        exit(EXIT_SUCCESS);
    }

【问题讨论】:

  • int tid = ...;tid++tid = ... 只是在处理 tid 中的普通整数值。它对地址或位置没有任何作用。要做你想做的事,请查看argument,以及它指向的位置。并将其视为指向 array 的第一个元素的指针。现在考虑如何获取数组的第二个元素(还要考虑线程运行时数组本身可能没有完全初始化,并且可能包含 indeterminate 值!)
  • 你的意思是直接添加到数组的第一个元素吗?像((void *)参数+1)。关于最后一点(未完全初始化的数组),我不确定如何处理它。我对容器和友好结构有一些经验,但我不是原始类型和内存管理的好朋友:/
  • I have tried a lot of combinations 那是学习 C 的错误方法。你需要结构化的学习,例如一本好书。
  • @SergeyA :很容易说“你需要更多的结构”。我知道我知道。你也许可以推荐一本特别好的书。那将是一个建设性的评论;)

标签: c multithreading pthreads


【解决方案1】:

在您的线程函数中,tidmainthread_args 数组的特定成员的。对此变量的任何更改都不会反映在其他地方。

与其立即取消引用转换后的参数,不如直接将其作为int *。然后你可以对其进行指针运算并进一步取消引用它。

void* TaskCode(void* argument) {
    int *tid = argument;
    tid++;
    *tid = *((int*)argument);
    printf("\nI have the value: \" %d \" and address: %p! \n", *tid, (void *)tid);
    return NULL;
}

【讨论】:

  • tid 的初始初始化之后,可以只做tid[1] = tid[0]。而且无论使用哪种方法,都需要实际初始化下一个“元素”,这在问题中的代码中并不能保证(特别是因为thread_args[NUM_THREADS]永远被初始化,但是仍在使用)。
  • 这不会编译:/ Threads.cpp:10:21: 错误:从‘void*’到‘int*’的无效转换 [-fpermissive] 10 | int tid = 参数; // 将 tid 设置为线程的值 | ^~~~~~~~ | | |无效
  • @Mylo 对我来说,这表明您不是用 C 编程,而是用 C++ 编程。在 C 中,void * 可以隐式转换为任何其他指针类型而无需强制转换。
  • @Someprogrammerdude 谢谢,我实际上将我的文件保存为 .cpp,直到现在我才看到区别。现在我把它改成了.c
猜你喜欢
  • 2010-10-17
  • 1970-01-01
  • 1970-01-01
  • 2011-04-27
  • 2019-09-16
  • 1970-01-01
  • 2013-07-19
  • 2014-12-02
  • 2014-10-17
相关资源
最近更新 更多