【问题标题】:Trying to pass an instance of a struct to a thread function with an integer and a double value尝试将结构的实例传递给具有整数和双精度值的线程函数
【发布时间】:2020-11-04 04:25:23
【问题描述】:

我正在尝试将结构的实例传递给线程,但由于某种原因,它正在打印整数的随机值,但双精度值的正确值?

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
//Pass an integer value and a double value to a thread (use struct!)
typedef struct param { 
    int val;
    double db;
}param_t;

void *myth(void *arg) 
{ 
    param_t myT, *myPt;
    myT = *((param_t*)arg);
    myPt = (param_t*)arg;
    
    printf("%d\n", myT.val);
    printf("%.3lf\n", myPt->db);
    pthread_exit(NULL);
}

void main() 
{ 
    pthread_t tid;
    int i = 3733;
    double d = 3733.001;
    param_t t_struct;
    param_t *p;
    p = malloc(sizeof(param_t));
    *p = t_struct;
    t_struct.val = i;
    t_struct.db = d;

    
    pthread_create(&tid, NULL, myth, (void *)&p);
    pthread_join(tid, NULL);
    return;
}

输出: 10969104 3733.001

【问题讨论】:

    标签: c pthreads


    【解决方案1】:

    一个问题来了:

    *p = t_struct;
    t_struct.val = i;
    t_struct.db = d;
    

    第一个赋值复制了未初始化的结构t_struct。然后初始化t_struct,但这只会初始化t_struct 本身。它修改p指向的副本。

    然后通过将指针传递给指针会使情况变得更糟。这意味着在线程函数myth 内部,参数arg 根本不指向结构。当您取消引用指针时,这会导致 未定义的行为

    我的建议是不要打扰p 或动态分配。而是将指针传递给原始结构 t_struct:

    pthread_create(&tid, NULL, myth, & t_struct);
    

    【讨论】:

    • 或者如果你坚持要通过p那么pthread_create(&amp;tid, NULL, myth, p);
    【解决方案2】:

    这毫无意义:

    param_t t_struct;
    param_t *p;
    p = malloc(sizeof(param_t));
    *p = t_struct;       // t_struct isn't initialized, so this is undefined behaviour.
    t_struct.val = i;    // Has no effect on `p` or `*p`.
    t_struct.db = d;     // Has no effect on `p` or `*p`.
    

    也许你要去

    param_t t_struct;
    param_t *p;
    p = malloc(sizeof(param_t));
    t_struct.val = i;
    t_struct.db = d;
    *p = t_struct;
    

    以下会更好:

    param_t t_struct;
    t_struct.val = i;
    t_struct.db = d;
    
    param_t *p = &t_struct;
    

    您还可以使用以下内容:

    param_t *p = malloc(sizeof(param_t));
    p->val = i;
    p->db = d;
    

    与之前的解决方案不同,最后一个解决方案不需要t_struct 在线程加入之前保持存在


    还有第二个问题。

    arg 确实是param_t **,但您将其视为param_t *

    固定:

    void *myth(void *arg)   // arg is really a param_t *
    { 
        param_t *p = (param_t*)arg;;
        printf("%d\n", p->val);
        printf("%.3lf\n", p->db);
        pthread_exit(NULL);
    }
    
    pthread_create(&tid, NULL, myth, p);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-15
      • 1970-01-01
      • 1970-01-01
      • 2022-01-12
      • 2010-09-22
      • 2017-05-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多