makecontext实现协程遇到问题
```
#include <unistd.h>
#include <ucontext.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#define INTERVAL 200000
#define DELAY 50000000
#define BOUND 15
#define STACKSIZE 4096
#define THREADS 16
ucontext_t context[THREADS], myCleanup, myMain;
int status[THREADS];
char myMainArr[STACKSIZE];
struct itimerval clocktimer;
int totalThreads = 0;
int currentThread = 0;
long pos[THREADS];
void cleanup(void);
void task1(int);
void task2(int);
void signalHandler(int signal);
int main( void )
{
char *myStack[THREADS];
char myCleanupStack[STACKSIZE];
int j;
/* initialize timer to send signal every 200 ms */
clocktimer.it_value.tv_sec = 0;
clocktimer.it_value.tv_usec = INTERVAL;
clocktimer.it_interval.tv_sec = 0;
clocktimer.it_interval.tv_usec = INTERVAL;
setitimer(ITIMER_REAL, &clocktimer, 0);
sigset(SIGALRM, signalHandler);
getcontext(&myCleanup);
myCleanup.uc_stack.ss_sp = myCleanupStack;
myCleanup.uc_stack.ss_size = STACKSIZE;
myCleanup.uc_link = &myMain;
makecontext(&myCleanup, (void (*)(void))cleanup, 0);
// set up your cleanup context here.
for (j = 0; j < THREADS; j++)
{
getcontext(&context[j]); // makecontext must get a context from getcontext
myStack[j] = (char *)malloc(sizeof(char) * STACKSIZE);
context[j].uc_stack.ss_sp = &myStack[j];
context[j].uc_stack.ss_size = STACKSIZE;
context[j].uc_link = &myCleanup;
// 1: ready, 2: running 0:finished
pos[j] = j;
if (j % 2 == 0){
printf("Creating task1 thread[%d]\n", j);
makecontext(&context[j], (void (*)(void))task1, 1, pos[j]);
// map the corresponding context to task1
}
else
{
printf("Creating task2 thread[%d]\n", j);
makecontext(&context[j], (void (*)(void))task2, 1, pos[j]);
// map the corresponding context to task2
}
// you may want to keep the status of each thread using the
// following array. 1 means ready to execute, 2 means currently
// executing, 0 means it has finished execution.
status[j] = 1;
// You can keep track of the number of task1 and task2 threads
// using totalThreads. When totalThreads is equal to 0, all
// tasks have finished and you can return to the main thread.
totalThreads++;
}
printf("Running threads\n");
status[currentThread] = 2;
swapcontext(&myMain, &context[currentThread]);
// start running your threads here.
for(j = 0; j < THREADS; j++)
{
free(myStack[j]);
}
printf("Program terminates successfully\n");
return 0;
}
void signalHandler(int signal)
{
//int nextThread;
int prev, i;
printf("Get a signal\n");
//int tmp = currentThread;
if (status[currentThread] != 0) {
//printf("status %d is %d\n", currentThread, status[currentThread]);
status[currentThread] = 1;
}
i = (currentThread + 1) % THREADS;
for (; i != currentThread; i = ((i + 1) % THREADS)) {
if (status[i] == 1) {
break;
}
}
prev = currentThread;
currentThread = i;
status[currentThread] = 2;
//printf("prev is: %d status is: %d currentThread is: %d status is:%d\n", prev, status[prev], currentThread, status[currentThread]);
swapcontext(&context[prev], &context[currentThread]);
return;
}
void cleanup() {
int prev;
status[currentThread] = 0;
totalThreads--;
if (totalThreads == 0) return;
int i = currentThread;
for (i = (currentThread + 1) % THREADS; i != currentThread; i = (i + 1) % THREADS) {
if (status[i] == 1) {
break;
}
}
prev = currentThread;
currentThread = i;
status[currentThread] = 2;
swapcontext(&context[prev], &context[currentThread]);
return;
}
void task1(int tid)
{
// self explanatory
int i, count = 1;
while(count <= BOUND){
for (i = 0; i < DELAY; i++);
printf ("task1 [tid = %d]: count = %d\n", tid, count++);
}
}
void task2( int tid)
{
// self explanatory
int i, count = 1;
while(count <= BOUND){
for (i = 0; i < DELAY/2; i++);
printf ("task2 [tid = %d]: count = %d\n", tid, count++);
}
}
```
代码如上所述,执行的时候遇到segment fault错误,第一次使用makecontext,不知道哪的问题,调试不出来,望大神支招。
代码实现的意思是:
模拟16个线程执行task1和task2,中间会有alarm信号中断,中断的时候会使用makecontext保存当前上下文,执行下一个上下文。
其中status保存当前线程的状态,0为结束,1为可以执行,2为执行中
最后,执行完成的线程会调用cleanup函数设置status为0,然后,alarm信号中断的时候不会选取该线程执行。
请指教。