释放Pthread中的指针

发布于 2025-01-25 14:09:47 字数 682 浏览 1 评论 0 原文

我想制作结构的副本,然后将其传递到pthread,然后在pthread线程中fileny将其释放。但是我无法将其弄出来,这只是在这一点上远远超出了我,我找不到有关传递克隆结构并在线程中释放它们的任何教程。伪代码以下:

typedef struct unit_t { int id; char value[20]; char pid[20]; char id[100]; int type; }

pthread_t th;

void* myThread(void *arg){ 
 how do i print a struct value and free arg in here?
 free(arg);
}

void someFunction(*unit){
 //create a local copy of struct
 unit_t *tmp = malloc(sizeof(struct unit_t));
 //clone initial *unit
 *tmp = *unit;

 //spawn thread
 if(pthread_create(&th, NULL, &myThread, &tmp) != 0) { 
  bwlog("failed to create thread");
  //free tmp if thread failed
  free(tmp);
 }else{
  pthread_detach(th);
 }
}

I want to make a copy of a struct, then pass it into pthread, and finaly free it inside the pthread thread. But i can't fingure this out, it's simply to far beyond me at this point and i can't find any tutorial about passing a cloned struct, and freeing them inside thread. Pseudo code below:

typedef struct unit_t { int id; char value[20]; char pid[20]; char id[100]; int type; }

pthread_t th;

void* myThread(void *arg){ 
 how do i print a struct value and free arg in here?
 free(arg);
}

void someFunction(*unit){
 //create a local copy of struct
 unit_t *tmp = malloc(sizeof(struct unit_t));
 //clone initial *unit
 *tmp = *unit;

 //spawn thread
 if(pthread_create(&th, NULL, &myThread, &tmp) != 0) { 
  bwlog("failed to create thread");
  //free tmp if thread failed
  free(tmp);
 }else{
  pthread_detach(th);
 }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

陌伤ぢ 2025-02-01 14:09:47

void *可以隐式转换为任何指针类型。

但是,请注意,通过& tmp (用自动存储持续时间)在您的代码中很危险,因为您不能确保 tmp 的nofollow noreferrer“> lifetime 匹配创建线程的寿命。

换句话说,& tmp 指向 somefunction 中的本地变量。 somefunction 可能会在线程完成执行之前返回,在这种情况下, arg 将是悬空指针

您要传递 tmp 的值(分配的存储持续时间)。

还请注意,函数的地址(& mythread )具有与函数本身相同的值( mythread )。运营商的地址在这里是多余的。

一个粗略的示例,没有任何错误处理,它连续产生了动态分配的内存的线程。

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

struct foo {
    int a;
    int b;
};

void *thread_runner(void *arg) {
    struct foo *data = arg;
    printf("%d + %d = %d\n", data->a, data->b, data->a + data->b);
    free(data);

    return NULL;
}

int main(void) {
    srand((unsigned) time(NULL));

    while (1) {
        pthread_t id;
        struct foo *data = malloc(sizeof *data);

        data->a = rand() / 2;
        data->b = rand() / 2;

        pthread_create(&id, NULL, thread_runner, data);
        pthread_detach(id);

        sleep(3);
    }
}

必须按照您的“克隆”结构来注意。这将被视为A 浅副本,为结构的字节副本执行字节。

虽然这对于您定义的结构很好,但是当结构包含指针(或嵌套指针)时,就会出现问题。这种结构的浅副本将导致两个结构都将相同的指针固定为一个对象。

像以前一样,当涉及线程时,指向对象的寿命可能与线程的寿命不符,或者指针是动态分配的内存,(难以回答的问题 释放的对象?

可能需要

A void * can be implicitly converted to any pointer type.

Note, however, that passing &tmp (the address of an object with automatic storage duration) is dangerous in your code, since you do not ensure that the lifetime of tmp matches the lifetime of the created thread.

In other words, &tmp points to a local variable in someFunction. someFunction may return before the thread finishes its execution, in which case arg will be a dangling pointer.

You want to pass the value of tmp (the address of an object with allocated storage duration).

Note also that the address of a function (&myThread) has same value as the function itself (myThread). The address-of operator is superfluous here.

A cursory example, with no error handling, that continuously spawns threads that are passed dynamically allocated memory.

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

struct foo {
    int a;
    int b;
};

void *thread_runner(void *arg) {
    struct foo *data = arg;
    printf("%d + %d = %d\n", data->a, data->b, data->a + data->b);
    free(data);

    return NULL;
}

int main(void) {
    srand((unsigned) time(NULL));

    while (1) {
        pthread_t id;
        struct foo *data = malloc(sizeof *data);

        data->a = rand() / 2;
        data->b = rand() / 2;

        pthread_create(&id, NULL, thread_runner, data);
        pthread_detach(id);

        sleep(3);
    }
}

Care must be taken with "cloning" a structure the way you have. This would be considered a shallow copy, performing a byte for byte copy of the structure.

While this is fine for the structure you have defined, a problem arises when a structure contains a pointer (or nested pointers). A shallow copy of such a structure would result in both structures holding the same pointer to a single object.

Like before, when threads are involved, the pointed-to-object's lifetime may not match the lifetime of a thread, or if the pointer is to dynamically allocated memory, the (difficult) question to answer becomes Where and when is the object freed?

A deep copy may be needed.

﹏半生如梦愿梦如真 2025-02-01 14:09:47

您确实说过您的帖子是伪代码,但有一些问题。

  1. 您忘记了实际 typedef ,并且有两个具有相同名称的字段:
typedef struct unit_t
{
    int id;
    char value[20];
    char pid[20];
    char strId[100];  // this cannot be named id, that already exists
    int type;
} unit_t; // need to add the new name at the end, and end it with a semicolon
  1. 始终检查 malloc 的返回值,
unit_t *tmp = malloc(sizeof(struct unit_t));
if (tmp == NULL) // handle error
  1. 无需传递 tmp ,它已经是指针。
pthread_create(&th, NULL, &myThread, tmp)
  1. 在线程函数中,您需要将参数降回适当的类型,对其进行操作,然后您可以 free it。您还应该适当地退出功能:
void* myThread(void *arg){ 
 unit_t* myDupeUnit = (unit_t*)arg;
 printf("id = %d\n", myDupeUnit->id);
 printf("strId = %s\n", myDupeUnit->strId);
 free(myDupeUnit);

 pthread_exit(NULL);
}

我不知道您在做什么的范围,但是我用 pthread_detach pthread_join 只是为了确保所有内容都在执行之前该过程终止。您可以找到一个有效的演示在这里

You did say your post is pseudo code, but it has a few problems.

  1. You forgot to actually typedef, and you have two fields with the same name:
typedef struct unit_t
{
    int id;
    char value[20];
    char pid[20];
    char strId[100];  // this cannot be named id, that already exists
    int type;
} unit_t; // need to add the new name at the end, and end it with a semicolon
  1. Always check the return value of malloc
unit_t *tmp = malloc(sizeof(struct unit_t));
if (tmp == NULL) // handle error
  1. No need to pass the address of tmp, it's already a pointer.
pthread_create(&th, NULL, &myThread, tmp)
  1. In your thread function, you need to cast the argument back to the appropriate type, do what you want with it, then you can free it. You should also exit the function appropriately:
void* myThread(void *arg){ 
 unit_t* myDupeUnit = (unit_t*)arg;
 printf("id = %d\n", myDupeUnit->id);
 printf("strId = %s\n", myDupeUnit->strId);
 free(myDupeUnit);

 pthread_exit(NULL);
}

I don't know the larger scope of what you're doing, but I replaced pthread_detach with pthread_join just to make sure everything executes before the process terminates. You can find a working demonstration here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文