简体   繁体   English

如何从线程返回结构?

[英]How do I return a struct from a thread?

I'm trying to learn how to return some value from a thread, but i don't get success. 我正在尝试学习如何从线程中返回一些值,但是我没有成功。 I've considered in my code that I can't return a global variable so I get memory from malloc , but I evidently have a problem in pthread_join . 我在代码中考虑过,我无法返回全局变量,所以我从malloc获取内存,但是pthread_join显然存在问题。

#include<stdio.h>
#include<stdlib.h>
#include <pthread.h>

struct DIRECCION{
    char street [20];
    int number;
}   ;



struct DIRECCION * pd = NULL;

void* show(void* dm){

    struct DIRECCION * di = (void*)dm;
    pd=(struct DIRECCION*)malloc(sizeof(struct DIRECCION));
    printf("\nHilo show\n");
    printf("Calle: %s\t",di->street);
    printf("Altura: %d\n",di->number);

    printf("Calle: ");
    scanf("%s",pd->street);
    printf("Altura: ");
    scanf("%d",&(pd->number));
    printf("me jui\n");


    return((void*)pd);
}



int main (void){

    pthread_t s_id;
    struct DIRECCION dm;
    struct DIRECCION  d ;


    printf("\nProceso\n");
    printf("Calle: ");
    scanf("%s",dm.street);
    printf("Altura: ");
    scanf("%d",&(dm.number));


    pthread_create( &s_id , NULL, (void*)&show, (void*)&dm);
    pthread_join( s_id , (void*)&d );

    printf("Calle: %s\t",(d.street));
    printf("Altura: %d\n",(d.number));
    free(pd);
    return 0;
}

First step -- get rid of all the casts. 第一步-摆脱所有演员阵容。 You don't need them, and they hide the errors you would otherwise get from the compiler that tell you exactly what you are doing wrong. 您不需要它们,它们会隐藏您从编译器中获得的错误,这些错误会告诉您确切的操作错误。

When you do that, you see immediately that the problem is your call to pthread_join -- you're trying to call it with a struct DIRECCION * when it needs a void ** . 当您执行此操作时,您会立即发现问题出在调用pthread_join -您试图在需要void **时使用struct DIRECCION *对其进行调用。 To fix it, you need to pass a void ** , which means you need a void * to take the address of: 要修复它,您需要传递一个void ** ,这意味着您需要一个void *来获取以下地址:

void *tmp;
struct DIRECCION *d;
pthread_join( s_id , &tmp );
d = tmp;
... do stuff with d->whatever

In your thread function you have: 在线程函数中,您具有:

pd=(struct DIRECCION*)malloc(sizeof(struct DIRECCION));
return((void*)pd);

Which is saying to return the address of the memory you allocated. 也就是说返回您分配的内存地址。 Then, in your main function, 然后,在您的主要功能中

struct DIRECCION  d ;
pthread_join( s_id , (void*)&d );

Which is saying to write the value returned by you thread function to the memory where d is stored. 就是说将线程函数返回的值写到存储d的内存中。 In other words, what you're writing to d is a struct DIRECCION* , not a struct DIRECCION . 换句话说,您写给dstruct DIRECCION* ,而不是struct DIRECCION

Try something like 尝试类似

#include<stdio.h>
#include<stdlib.h>
#include <pthread.h>

struct DIRECCION{
  char street [20];
  int number;
}   ;

void* show(void* dm){
  struct DIRECCION * pd = NULL;
  struct DIRECCION * di = (void*)dm;
  pd=(struct DIRECCION*)malloc(sizeof(struct DIRECCION));
  printf("\nHilo show\n");
  printf("Calle: %s\t",di->street);
  printf("Altura: %d\n",di->number);

  printf("Calle: ");
  scanf("%s",pd->street);
  printf("Altura: ");
  scanf("%d",&(pd->number));
  printf("me jui\n");

  return((void*)pd);
}

int main (void){
  pthread_t s_id;
  struct DIRECCION dm;
  struct DIRECCION*  d ;


  printf("\nProceso\n");
  printf("Calle: ");
  scanf("%s",dm.street);
  printf("Altura: ");
  scanf("%d",&(dm.number));


  pthread_create( &s_id , NULL, (void*)&show, (void*)&dm);
  pthread_join( s_id , (void**)&d );

  printf("Calle: %s\t",(d->street));
  printf("Altura: %d\n",(d->number));
  free(d);
  return 0;
}

The code in show() is OK, aside 除了show()的代码还可以,

  • all those casts, which are completely useless in C. 所有这些强制转换,在C语言中完全没有用
  • and the fact that pd is defined globally 以及pd是全局定义的事实

     struct DIRECCION * pd = NULL; void* show(void* dm) { ... 

    which is not required. 这不是必需的。 Defined pd locally to show() : 在本地将pd定义为show()

     void* show(void* dm) { struct DIRECCION * pd = dm; ... 

In main() a clean way to pull the pointer value returned by show() would be: main() ,清除show()返回的指针值的一种干净方法是:

int main(void)
{
  ...

  {
    void * pv;
    pthread_join(s_id, &pv);

    /* Find the value inside pv here. */
  }

Doing as above there are two possibilities to go on with the pointer value retrieved fro pthread_join() : 如上所述,通过pthread_join()检索指针值有两种可能性:

  • Use the pointer value as is like so: 像这样使用指针值:

     int main(void) { struct DIRECCION * pd; ... { void * pv; pthread_join(s_id, &pv); pd = pv; } printf("Calle: %s\\t", pd->street); ... 
  • Dereference the pointer value and copy what it points to into suitable structure (the memory it points to is not needed afterwards, so free it to a avoid a leak): 解引用指针值并将其指向的内容复制到合适的结构中(此后不再需要指向的内存,因此请释放它以免泄漏):

     int main(void) { struct DIRECCION d; ... { void * pv; pthread_join(s_id, &pv); d = *((struct DIRECCION *) pv); /* The only cast necessary in fact. */ free(pv); /* This frees what has been allocated in `show()`. */ } printf("Calle: %s\\t", d.street); ... 

Please note that pthread_join() may fail, so it is strongly recommended to test the value it returns for failure. 请注意, pthread_join()可能会失败,因此强烈建议测试失败时返回的值。

If pthread_join() succeeded the pointer-value it returns may still be NULL , so testing this is essential before dereferencing the pointer value. 如果pthread_join()成功通过了指针值,则返回的值可能仍为NULL ,因此在取消引用指针值之前必须进行测试。

So a safe way to (try to) pull the pointer value from pthread_join() would be: 因此,一种安全的方法(尝试从pthread_join()提取指针值pthread_join()将是:

int main(void)
{
  ...

  {
    void * pv;
    int result = pthread_join(s_id, &pv);
    if (0 != result)
    {
      fprintf("pthread_join() failed: %s\n", strerror(result));
      exit(EXIT_FAILURE); /* EXIT_x come with stdlib.h. */
    }

    if (NULL == pv)
    {
      /* Handle this case here or exit() as well. */
    }
    else
    {
      /* Use the value inside pv here. */
    }
  }

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

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