C 用户级线程
我正在尝试创建用户级线程。这是我的代码示例。有人能帮我解决这个项目的问题吗C 用户级线程,c,C,我正在尝试创建用户级线程。这是我的代码示例。有人能帮我解决这个项目的问题吗 #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][81
#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;
}
谢谢您有一个未定义的行为情况
在thread\u create
中,首先要增加thread\u计数器。因此,当您创建第二个线程时,线程计数器将是2
。然后访问堆栈[2]
,这将为您提供未定义的行为
您还可以将上下文的uc\u链接
成员硬编码到&tcb[0]。上下文
,由于线程计数器
的“过早”增量,它从未初始化
但主要的问题是,您实际上并没有创建一个新的上下文,而是获取当前线程的上下文。您应该为每个线程使用。在thread\u yield
函数中,为什么要切换变量static
?无论如何,每次调用时都将该值设置为零。与thread\u create
函数中的变量s
相同。在代码中使用s和swithed没有任何意义。@JoachimPileborg。让static
关键字被删除。但它给出了相同的输出。@Koushik<代码>无法直接检测getcontext()的返回是来自第一次调用,还是通过setcontext()调用。用户必须发明自己的簿记设备
。变量s
和switched
用于此目的。谢谢Joachim Pileborg。你是对的。但是,即使我将代码stack[thread\u counter]
更改为stack[thread\u counter-1]
,o/p也没有任何变化。@Ravi用其他问题更新了我的答案。谢谢JoachimPileborg的帮助,但是1。我不明白你所说的“创建上下文”是什么意思tcb[0]。默认情况下,当第一次调用thread\u yield
时,将初始化上下文。对于makecontext
,我们仅限于根据我们的要求使用getcontext
和setcontext
。@Ravi在这种情况下,它很可能是一个旧答案,现在已删除,即主线程在两个子线程完成之前退出。在屈服于第一个线程之后,主程序应该进入一个循环,并屈服于所有未完成的线程,只要存在未完成的线程。当所有线程首先退出时,主程序可能会退出。
start f1
start f2
finish f2