0

ユーザーレベルのスレッドを作成しようとしています。これが私のコードのサンプルです。このプログラムの問題点を教えてください。

#include<stdio.h>
#include<ucontext.h>

int thread_counter = 0;
int thread1, thread2;
int who_am_i;

struct TCB {
    ucontext_t context;
    void (* fun_ptr)();
};
struct TCB tcb[3];
char stack[2][8192];


//----------------------
int thread_create(void (*fun)()) {
    static volatile int s;
    thread_counter++;
    s = 0;
    getcontext(&tcb[thread_counter].context);

    if(!s) {
        tcb[thread_counter].context.uc_stack.ss_sp   = stack[thread_counter];
        tcb[thread_counter].context.uc_stack.ss_size = sizeof(stack[thread_counter]);
        tcb[thread_counter].context.uc_link          = &tcb[0].context;
        tcb[thread_counter].fun_ptr                  = fun;
        s = 1;
    }
    else {
        tcb[who_am_i].fun_ptr();
    }

    return thread_counter;
}


void thread_yield(int next_thread) {
    static volatile int switched;
    switched = 0;
    getcontext(&tcb[who_am_i].context);

    if(!switched) {
        switched = 1;
        who_am_i = next_thread;
        setcontext(&tcb[next_thread].context);
    }
}


//----------------------
void f1() {
    printf("start f1\n");
    thread_yield(thread2);
    printf("finish f1:\n");
}

void f2() {
    printf("start f2\n");
    thread_yield(thread1);
    printf("finish f2\n");
}


//----------------------
int main() {
    thread1 = thread_create(f1);
    thread2 = thread_create(f2);

    who_am_i = 0;
    thread_yield(thread1);
    return 0;
}

スレッドが正しく切り替えられていません。実行すると、次の出力が得られます。

start f1
start f2
finish f2

ありがとうございました

4

1 に答える 1

0

未定義の動作状況があります。

thread_createあなたが最初に行うことを増やしますthread_counter。したがって、2 番目のスレッドを作成するthread_counterと、2. 次に、これにアクセスstack[2]すると、未定義の動作が発生します。


uc_linkまた、コンテキストのメンバーを にハードコーディング&tcb[0].contextしますthread_counter

しかし、主な問題は、実際に新しいコンテキストを作成するのではなく、現在のスレッドのコンテキストを取得するだけであることです。makecontext代わりに for each threadを使用する必要があります。

于 2013-02-19T08:33:11.100 に答える