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

私の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 のジャンク値を取得します。私が見逃しているのは何ですか。

4

1 に答える 1

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

しかし、それはメモリ リークが発生するのを待っているため、可能であれば構造体を値で返します。

于 2013-09-06T21:44:38.870 に答える