如何从线程返回结构?

时间:2019-04-13 22:47:32

标签: c linux pthreads

我正在尝试学习如何从线程中返回一些值,但是我没有成功。我在我的代码中考虑过,我无法返回全局变量,所以我从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;
}

3 个答案:

答案 0 :(得分:2)

第一步-摆脱所有演员阵容。您不需要它们,它们会隐藏您从编译器中获得的错误,这些错误会告诉您确切的操作错误。

这样做时,您会立即发现问题出在您对pthread_join的调用上-您正试图在需要struct DIRECCION *时使用void **对其进行调用。要解决此问题,您需要传递一个void **,这意味着您需要一个void *才能获得以下地址:

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

答案 1 :(得分:1)

在线程函数中,您具有:

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

这是说要返回您分配的内存的地址。然后,在您的主要功能中,

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

这就是说将线程函数返回的值写入存储d的内存中。换句话说,您要写入的dstruct DIRECCION*,而不是struct DIRECCION

尝试类似

#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;
}

答案 2 :(得分:1)

除了{p},show()中的代码还可以

  • 所有这些强制转换,在C语言中完全没有用。
  • pd是全局定义的事实

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

    ,不是必需的。在pd本地定义show()

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

main()中,一种简单的方法来提取show()返回的指针值将是:

int main(void)
{
  ...

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

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

执行上述操作时,可以使用两种方法继续从pthread_join()检索指针值:

  • 按如下方式使用指针值:

    int main(void)
    {
      struct DIRECCION * pd;
      ...
    
      {
        void * pv;
        pthread_join(s_id, &pv);
    
        pd = pv;
      }
    
      printf("Calle: %s\t", pd->street);
    
      ...
    
  • 取消引用指针值并将其指向的内容复制到合适的结构中(此后不再需要指向的内存,因此请释放它以免泄漏):

    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);
    
      ...
    

请注意,pthread_join()可能会失败,因此强烈建议测试失败时返回的值。

如果pthread_join()成功地返回了指针值,则返回的值可能仍为NULL,因此在取消引用指针值之前必须进行测试。

因此(尝试)从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. */
    }
  }