我正在尝试创建一个线程库,我的线程是一个 struct
类型。必须遵循某个接口(interface),因为我需要按值传递 thread
。例如:要加入一个线程,我的代码如下:
int thread_join(thread_t thread, void **status1)
{
printf("Joining thread\n");
long int thId = thread.id;
printf("Thread id: %ld\n", thId);
gtthread_t * thrd = getThreadFromID(thId);
while(thrd->status != EXIT)
{
}
status1 = &(thrd->ret_value);
return 0;
}
然后我将 thread_t
类型的 struct
传递给此函数。我的问题是当我在调用函数中看到线程的 ID 时,它显示正确但是当我在 thread_join
函数中检查它时它显示为 0。调用函数如下:
void* caller(void* arg)
{
thread_t th;
thread_create(&th, some_function, NULL);
thread_join(th, NULL);
while(1);
}
Thread create 将线程的 ID 初始化为非零值,并启动与其关联的函数。
我的线程结构(和其他相关结构是):
typedef enum
{
RUNNING,
WAITING,
CANCEL,
EXIT
} stat;
//Thread
typedef struct
{
ucontext_t t_ctxt;
long int id;
stat status;
void * ret_value;
int isMain;
} thread_t;
int thread_create(thread_t *thread, void *(*start_routine)(void *), void *arg)
{
thread = (thread_t *)malloc(sizeof(thread_t));
thread->id = ++count;
thread->status = RUNNING;
thread->ret_value = NULL;
thread->isMain = 0;
if(getcontext(&(thread->t_ctxt)) == -1)
handle_error("getcontext");
thread->t_ctxt.uc_stack.ss_sp = malloc(SIGSTKSZ);
thread->t_ctxt.uc_stack.ss_size = SIGSTKSZ;
thread->t_ctxt.uc_link = &sched_ctxt;
makecontext(&thread->t_ctxt, (void (*)(void))wrap_func, 2, (void (*)(void))start_routine, arg);
enqueue(gQ, thread);
printf("Thread id: %ld\n", thread->id);
swapcontext(&(curr_thread->t_ctxt),&sched_ctxt);
return 0;
}
为什么会这样?毕竟,我是按值传递的,这应该创建一个具有相同值的 thread
副本。谢谢。
编辑:
基本上我有一个线程队列,并且有一个循环调度程序。我也可以在此处发布该代码,但我确信这是不必要的,并且该代码可以正常工作。
编辑2:
我正在从这段代码制作一个头文件,并将该头文件包含在另一个文件中以对其进行测试。我所有的 thread_t
变量都是静态的。调用者是一个包含我的头文件的函数。
最佳答案
这一行是什么:
thread = (thread_t *)malloc(sizeof(thread_t));
为了?
您向 thread_create()
传递一个地址,该地址引用 caller()
中定义的 struct thread_t
作为 auto
变量。
按照您的做法,您将内存分配给传递给 thread_create()
的指针并对其进行初始化并在返回时忘记地址。
代码永远不会写入传入地址所引用的内存!除此之外,这是内存泄漏。
要解决此问题,只需删除上面引用的代码行即可。
关于c - 按值将结构传递给另一个函数会将其初始化为零,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21681243/