我正在尝试创建一个线程库。 MyThreadCreate
返回MyThread
类型的对象。 E.g:
struct MyThread
{
ucontext_t Context;
ThreadStatus Status;
int ThreadId;
};
typedef struct MyThread MyThread;
void * MyThreadCreate(void(*start_funct)(void *), void *args)
{
MyThread temp;
char *stack;
stack = (char *)malloc(8192*sizeof(char));
ucontext_t tempContext;
if (getcontext(&tempContext) == -1)
temp->ThreadId = 0;
tempContext.uc_stack.ss_sp = stack;
tempContext.uc_stack.ss_size = 8192*sizeof(char);
tempContext.uc_link = NULL;
makecontext(&tempContext,(void(*)(void))start_funct,1, args);
temp->Context = tempContext;
temp->Status = READY;
temp->ParentThread = currentThread;
temp->ThreadId = NEW_THREAD_ID++;
return temp;
}
在我的client.c
中,我打电话如下。
MyThread T;
T = (MyThread)MyThreadCreate(t0, (void *)n2);
MyThreadJoin(T);
在MyThreadJoin中,当我检查T的threadId的值时,我得到一个随机值。
void MyThreadJoin(MyThread thread); //defintion for MyThreadJoin
更新部分: 当我尝试返回一个名为MyThread的对象时,我在调用MyThreadCreate后立即收到分段错误。 另外,请注意我包含一个头文件(我无法更改),其中包含以下定义。 typedef void * MyThread 因此,代码仅在我为MyThreadCreate返回void *时才有效,而在MyThread时则无效。但即使代码工作正常,我也无法在这种情况下获得threadId。 可以告诉我哪里出错了。
当我试图将MyTHreadCreate的返回值保持为MyThread时,它会引发分段错误。所以我把它变成了void *并且我能够获得该对象然后用它来调用MyThreadJoin,但是我得到了MyThreadId的垃圾值。我错过了什么。
答案 0 :(得分:4)
问题归结为:
void * MyThreadCreate(...)
{
MyThread temp;
// manipulate temp
return temp;
}
外部代码只期望堆栈上有void *
,因此只保留sizeof(void *)
个temp
个字节。尝试访问除此之外的任何内容,并在堆栈中获得随机垃圾。
相反,您的函数应该像这样返回MyThread
:
MyThread MyThreadCreate(...)
{
MyThread temp;
// manipulate temp
return temp;
}
或者,如果必须将void *
返回到与其他代码的接口,则必须在堆上分配返回值:
void * MyThreadCreate(...)
{
MyThread *temp = malloc(sizeof(MyThread));
// manipulate temp
return temp;
}
但这是一个等待发生的内存泄漏,所以如果可能的话,我会按值返回结构。