Всем привет
есть такая реализация сопрограмм
#define _WIN32_WINNT 0x400
#include <windows.h>
#include <stdio.h>
////////////////////////////////////////////////////////////////////////////////
// занимается превращением потока в нить и
// гарантирует, что это будет сделано один раз
class GenBase
{
public:
static volatile LONG tls_;
GenBase()
{
DWORD newtls = ::TlsAlloc();
DWORD oldtls = ::InterlockedCompareExchange(&tls_, newtls, 0);
if (oldtls) ::TlsFree(newtls);
if (::TlsGetValue(tls_)==0)
{
::TlsSetValue(tls_, (LPVOID)1);
base_fiber_=::ConvertThreadToFiber(0);
} else
{
base_fiber_=::GetCurrentFiber();
}
}
protected:
LPVOID base_fiber_;
};
////////////////////////////////////////////////////////////////////////////////
// где-то в cpp файле
volatile LONG GenBase::tls_ = 0;
////////////////////////////////////////////////////////////////////////////////
// собственно генератор
template<typename Result>
class Generator : public GenBase
{
public:
Generator()
: terminated_(false)
{
child_fiber_=::CreateFiber(0,
FiberStartProc,
reinterpret_cast<LPVOID>(this));
}
~Generator()
{
DeleteFiber(child_fiber_);
}
protected:
void yield(Result res)
{
result_ = res;
SwitchToFiber(base_fiber_);
}
private:
static void CALLBACK FiberStartProc(LPVOID context)
{
reinterpret_cast<Generator*>(context)->start_fiber();
}
virtual void proceed() {}
void start_fiber()
{
proceed();
terminated_=true;
SwitchToFiber(base_fiber_);
}
public:
Result operator()()
{
// завершение функии нити фатально
if (terminated_)
throw "error";
::SwitchToFiber(child_fiber_);
return result_;
}
private:
LPVOID child_fiber_;
Result result_;
bool terminated_;
};
class Multi : public Generator<int>
{
public:
void proceed()
{
// функция должна быть вечной
// если она завершиться это приведет
// к остановке всего потока
for(unsigned index=0;; index+=2)
yield(index);
}
};
int main()
{
Multi gen;
Multi gen2;
for(unsigned index=0; index<100; ++index)
{
int a = gen();
int b = gen2();
printf("index = %d result = %d %d \n", index, a, b);
}
return 0;
}
тут подробнее:
http://www.rsdn.ru/forum/cpp/1687242.flat.aspxАвтор: Cyberax
Дата: 18.02.06
есть ли примеры удачного применения из реальной жизни ?
интересно было бы посмотреть или хотя бы интересные мысли..
по удачному применению услышать