基本上我正在嘗試的是在具有上下文切換的單個線程上模擬多線程。我每10微秒設置一次鬧鐘,並將上下文從一個切換到另一個線程。問題在於,大約有五分之一的運行結束時會在報警完成swapcontext後發生seg故障,至少這是我用gdb跟蹤它的地方。報警處理程序中的swapcontext之後的分段錯誤
這裏是我的源文件 main.c中
#include "umt.h"
void f()
{
int x = 10;
printf("starting thread\n");
while(x)
{
printf("thread %d\n", x);
sleep(1);
x--;
}
}
int main()
{
int x = 0, y, z;
umt_init();
y = umt_thread_create(f);
printf("starting main\n");
if(y == 0)
{
printf("Problems with creating thread\n");
return;
}
x = 10;
z = 1;
while(x)
{
printf("main\n");
x--;
}
umt_thread_join(y);
printf("done waiting\n");
return 0;
}
UMT.h
#include <sys/time.h>
#include <stdio.h>
#include <signal.h>
#include <ucontext.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
typedef struct _umt_thread
{
int thread_id;
ucontext_t context;
void (*handler)(void);
int hasFinished;
}umt_thread, *pumt_thread;
void umt_init();
int umt_thread_create(void (*handler)(void));
void umt_thread_join(int thr);
和umt.c
#include "umt.h"
#define MAIN_CONTEXT 0
#define STACK_SIZE 1638400
int currentThread;
char threadpool[15];
pumt_thread threads;
void signal_thread_finish();
void thread_handler()
{
threads[currentThread].handler();
signal_thread_finish();
}
void thread_scheduler();
void signal_thread_finish()
{
threads[currentThread].hasFinished = TRUE;
threadpool[currentThread] = 0;
thread_scheduler();
}
void thread_scheduler()
{
int nextThread = 0, curThread = 0;
int x = 0;
ucontext_t *con1, *con2;
nextThread = currentThread + 1;
while(1)
{
if(nextThread == 15)
nextThread = 0;
if(nextThread == currentThread)
break;
if(threadpool[nextThread] == 1)
break;
nextThread++;
}
if(nextThread == currentThread)
return;
curThread = currentThread;
currentThread = nextThread;
con1 = &(threads[curThread].context);
con2 = &(threads[nextThread].context);
x = swapcontext(con1, con2);
}
void umt_init()
{
ucontext_t context;
struct itimerval mytimer;
int i;
stack_t new_stack;
getcontext(&context);
threads = (pumt_thread)malloc(sizeof(umt_thread) * 15);
threads[MAIN_CONTEXT].thread_id = MAIN_CONTEXT;
threads[MAIN_CONTEXT].context = context;
threadpool[MAIN_CONTEXT] = 1;
for(i = 1;i<15;i++)
{
threadpool[i] = 0;
}
currentThread = 0;
new_stack.ss_sp = (char*)malloc(STACK_SIZE);
new_stack.ss_size = STACK_SIZE;
new_stack.ss_flags = 0;
i = sigaltstack(&new_stack, NULL);
if(i != 0)
{
printf("problems assigning new stack for signaling\n");
}
signal(SIGALRM, thread_scheduler);
mytimer.it_interval.tv_sec = 0;
mytimer.it_interval.tv_usec = 10;
mytimer.it_value.tv_sec = 0;
mytimer.it_value.tv_usec = 5;
setitimer(ITIMER_REAL, &mytimer, 0);
}
int umt_thread_create(void (*handler)(void))
{
ucontext_t context;
int i, pos;
for(i = 1;i<15;i++)
{
if(threadpool[i] == 0)
{
pos = i;
break;
}
}
if(i == 15)
{
printf("No empty space in the threadpool\n");
return -1;
}
if(getcontext(&context) == -1)
{
printf("Problems getting context\n");
return 0;
}
context.uc_link = 0;//&(threads[MAIN_CONTEXT].context);
context.uc_stack.ss_sp = (char*)malloc(STACK_SIZE);
if(context.uc_stack.ss_sp == NULL)
{
printf("Problems with allocating stack\n");
}
context.uc_stack.ss_size = STACK_SIZE;
context.uc_stack.ss_flags = 0;
makecontext(&context, thread_handler, 0);
threads[pos].thread_id = pos;
threads[pos].context = context;
threads[pos].handler = handler;
threads[pos].hasFinished = FALSE;
threadpool[pos] = 1;
printf("Created thread on pos %d\n", pos);
return pos;
}
void umt_thread_join(int tid)
{
while(!threads[tid].hasFinished)
{
}
}
我嘗試了很多組合,並試圖追蹤通過指令,但不能得出一個結論或想法,以什麼可能會導致此seg錯誤。由於