我正在尝试在 c 中实现简单的用户级线程库。当一个线程启动并且该线程调用第二个线程时。这第二个线程运行正确,但是当它退出程序崩溃时。这是我的编码。
//**********************************************
#include <setjmp.h>
typedef void *any_ptr;
/* Define Boolean type, and associated constants. */
typedef int Boolean;
typedef void (*ThreadFunc)(any_ptr);
#define TRUE ((Boolean)1);
#define FALSE ((Boolean)0);
typedef struct TheadSystem
{
queue<any_ptr> readyQ;
// currently executing thread
jmp_buf lastContext; // location on which the system jumps after all threads have exited
char name[30]; // optional name string of a thread, may be used for debugging
jmp_buf context; // saved context of this thread
signal_t *sig; // signal that wakes up a waiting thread
ThreadFunc func; // function that this thread started executing
any_ptr arg;
}TheadSystem;
void t_start(ThreadFunc f, any_ptr v, char *name);
void t_yield();
void block();
void unblock();
void t_sig(Condition cond, any_ptr val, Boolean queue_signal);
void t_fork(ThreadFunc f, any_ptr v, char *name);
void t_exit(int val);
我的threads.h实现
#include "threads.h"
#include<iostream>
#include<queue>
using namespace std;
TheadSystem th;
queue<any_ptr> blocked_queue;
jmp_buf set_env,ready_env,yeild_buf;
void t_start(ThreadFunc f, any_ptr v, char *name){
if(!th.ready_queue.empty()){
cout<<"sorry thread already started now you have to create by t_fork:"<<endl;
}
else{
th.ready_queue.push(th.context);
if(!setjmp(th.context)){
memcpy(th.lastContext,th.context,sizeof(jmp_buf));
th.arg=v;
th.func=f;
//memcpy(th.currentThread->context,set_env,sizeof(jmp_buf));
//cout<<"when jmp buf set then:"<<endl;
th.ready_queue.push(th.context);
th.func(th.arg);
}
//cout<<"after come back from long jump:"<<endl;
}
}
void t_yield(){
jmp_buf *j=(jmp_buf *)th.ready_queue.front();
th.ready_queue.front()=th.context;
longjmp(*j,2);
}
void t_fork(ThreadFunc f, any_ptr v, char *name){
memcpy(th.lastContext,th.context,sizeof(jmp_buf));
if(!setjmp(th.context)){
f(v);
th.ready_queue.push(th.context);
}else
{
}
}//end of t_fork
void t_exit(int val){
cout<<"before long jump in t_exit"<<endl;
jmp_buf *j=(jmp_buf *)th.ready_queue.front();
th.ready_queue.pop();
longjmp(*j,2);
}
void block(){
blocked_queue.push(th.context);
jmp_buf *j=(jmp_buf *)th.ready_queue.front();
th.ready_queue.pop();
longjmp(*j,2);
}
void unblock(){
th.ready_queue.push(th.context);
jmp_buf *j=(jmp_buf *)blocked_queue.front();
blocked_queue.pop();
longjmp(*j,2);
}
我的测试用例是
#include<iostream>
#include<setjmp.h>
#include<stdio.h>
#include "threads.h"
#include<queue>
using namespace std;
void fun2(any_ptr v){
cout<<"in 2nd function:"<<endl;
t_exit(0);
}
void helloworld(any_ptr v){
cout<<"in hello world from start"<<endl;
t_fork(fun2,NULL,"no value");
cout<<"after second thread:"<<endl;
cout<<"before exit"<<endl;
t_exit(0);
}
void main(){
cout<<"1 start"<<endl;
t_start(helloworld, NULL, "my function");
cout<<"main function"<<endl;
}//end of void main