0

我正在尝试创建一个线程库。MyThreadCreate返回一个类型的对象MyThread。例如:

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

在 myclient.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 的垃圾值。我错过了什么。

4

1 回答 1

4

问题归结为:

void * MyThreadCreate(...)
{
    MyThread temp;
    // manipulate temp
    return temp;
}

外部代码只期望void *堆栈上的 a ,因此只保留第一个sizeof(void *)字节temp。尝试访问除此之外的任何内容,您会在堆栈上得到随机垃圾。

相反,您的函数应该MyThread像这样返回:

MyThread MyThreadCreate(...)
{
    MyThread temp;
    // manipulate temp
    return temp;
}

或者,如果您必须返回一个void *与其他代码的接口,那么您必须在堆上分配返回值:

void * MyThreadCreate(...)
{
    MyThread *temp = malloc(sizeof(MyThread));
    // manipulate temp
    return temp;
}

但这是等待发生的内存泄漏,所以如果可能的话,我会按值返回结构。

于 2013-09-06T21:44:38.870 回答