Ключевые слова: example, threads, (найти похожие документы)
Date: Mon, 4 Mar 2002 20:43:56 +0000 (UTC)
From: Vladimir Dozen <dozen@osw.com.ru>
Newsgroups: fido7.ru.unix.prog
Subject: Пример использования тредов.
> > В-третьих, возможно самому родить простые кооперативные нити
> А по подробнее, what's it?
Тебе это не подойдет, у тебя много параллельных read/write,
а у кооперативных нитей нить-то на самом деле одна, и если
она заснула на write(), то и остальные спят.
Для общего развития можешь посмотреть листинг. Список нитей
сделан страшно криво, но это был просто proof of concept.
Собрано под фряху, под линуксом надо заменить макрос SET_STACK_JB;
/**
* Starts new thread.
* @return Thread id of newly created thread.
* @param start Address of thread procedure.
* @param stacksz Stack size for thread.
*/
jmpthread_t jmpthread_create(void (*start)(jmpthread_t),int stacksz=8192)
{
++maxthread;
++cntthread;
jmpthread_t iam = maxthread-1;
threads_used[iam] = true;
int rc = setjmp(threads[iam]);
if( rc == 0 )
{
// setup new stack
char* stk = (char*)malloc(stacksz+sizeof(jmp_buf));
SET_STACK_JB(threads[iam],stk+stacksz);
threads_start[iam] = start;
return iam;
}
else if( rc == 1 )
{
// run thread; we have moved stack, so we cannot use address
// of start from parameters and 'iam' from stack; use saved
// address and curthread instead
threads_start[curthread](curthread);
}
else
{
// unexpected error
exit(1);
}
return -1;
}
/**
* Stops thread.
*/
void jmpthread_exit(jmpthread_t tid)
{
threads_used[tid] = false;
--cntthread;
// no more threads; return to main routine
if( cntthread == 0 ) longjmp(mainthread,1);
jmpthread_sched(-1);
}
/**
* Passes control back to scheduler.
* @param tid Thread id of current thread.
*/
void jmpthread_yield(jmpthread_t tid)
{
// if we called from main routing, just pick a thread randomly
if( tid < 0 )
{
jmpthread_sched(tid);
return;
}
// save context
int rc = setjmp(threads[tid]);
if( rc == 0 )
{
// saved previous active thread; activate another
// choose random thread from list
jmpthread_sched(tid);
}
else if( rc == 1 )
{
// just reactivated
return;
}
else
{
// oops; error?
exit(1);
}
}
void f1(jmpthread_t tid)
{
stack_location("f1");
// to check we have correct stack pointer
int localdata = tid;
DIR* dir;
notify("entered f1",localdata);
dir = opendir("/etc");
jmpthread_yield(tid);