协程,其思想是,一系列互相依赖的协程间依次使用CPU,每次只有一个协程工作,而其他协程处于休眠状态。协程可以在运行期间的某个点上暂停执行,并在恢复运行时从暂停的点上继续执行。在WINDOWS上,微软提供了纤程API。下午花点时间撸了下代码,大家看看,挺有意思的API,适合并发处理,能简洁代码的逻辑
#include "stdafx.h"
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <ostream>
#include <map>
#include <string>
struct IFiberFactory
{
virtual void yield(const char* name) = 0;
virtual void end() = 0;
virtual void send_data(void* data, size_t sizelen) = 0;
virtual void recv_data(void** data, size_t* sizelen) = 0;
};
class CFiber
{
public:
CFiber(LPFIBER_START_ROUTINE lpStartAddress)
{
m_Fiber = CreateFiber(0, lpStartAddress, this);
}
~CFiber()
{
DeleteFiber(m_Fiber);
}
void yield(const char* name)
{
m_FiberFactory->yield(name);
}
void end()
{
m_FiberFactory->end();
}
void send_data(void* data, size_t sizelen)
{
m_FiberFactory->send_data(data, sizelen);
}
void recv_data(void** data, size_t* sizelen)
{
m_FiberFactory->recv_data(data, sizelen);
}
void set_data(void* p)
{
m_data = p;
}
void* get_data()
{
return m_data;
}
void set_shareData(void* p)
{
m_shareData = p;
}
void* get_shareData()
{
return m_shareData;
}
void* get_Fiber()
{
return m_Fiber;
}
void set_FiberFactory(void* p)
{
m_FiberFactory = reinterpret_cast<IFiberFactory*>( p );
}
private:
void* m_Fiber;
void* m_data;
void* m_shareData;
IFiberFactory* m_FiberFactory;
};
class CFiberFactory : public IFiberFactory
{
public:
CFiberFactory()
{
m_Fiber = ConvertThreadToFiber(this);
}
~CFiberFactory()
{
std::map<const char* , CFiber*>::iterator it = m_mapFibers.begin();
for(it; it != m_mapFibers.end(); it++)
{
CFiber* Fiber = it->second;
delete Fiber;
}
DeleteFiber(m_Fiber);
}
CFiber* AddFilber(const char* name, LPFIBER_START_ROUTINE lpStartAddress)
{
std::map<const char* , CFiber*>::iterator it = m_mapFibers.find(name);
if(it != m_mapFibers.end())
{
return NULL;
}
CFiber* Fiber = new (std::nothrow) CFiber(lpStartAddress);
Fiber->set_shareData(m_shareData);
Fiber->set_FiberFactory(this);
m_mapFibers[name] = Fiber;
return Fiber;
}
BOOLEAN DelFilber(const char* name)
{
std::map<const char* , CFiber*>::iterator it = m_mapFibers.find(name);
if(it == m_mapFibers.end())
{
return FALSE;
}
std::map<const char* , CFiber*>::mapped_type Fiber = it->second;
delete Fiber;
return TRUE;
}
void yield(const char* name)
{
std::map<const char* , CFiber*>::iterator it = m_mapFibers.find(name);
if(it != m_mapFibers.end())
{
CFiber* Fiber = it->second;
SwitchToFiber(Fiber->get_Fiber());
}
}
void end()
{
SwitchToFiber(m_Fiber);
}
CFiber* findFiber(const char* name)
{
std::map<const char* , CFiber*>::iterator it = m_mapFibers.find(name);
if(it != m_mapFibers.end())
{
CFiber* Fiber = it->second;
return Fiber;
}
return NULL;
}
void send_data(void* data, size_t sizelen)
{
m_data = data;
m_datalen = sizelen;
}
void recv_data(void** data, size_t* sizelen)
{
*data = m_data;
*sizelen = m_datalen;
}
private:
void* m_Fiber;
std::map<const char* , CFiber*> m_mapFibers;
void* m_shareData;
void* m_data;
size_t m_datalen;
};
void __stdcall Fiber_Reader(LPVOID lpFiberParameter)
{
CFiber* Fiber = (CFiber*)lpFiberParameter;
int i = 0;
while(1)
{
void* data;
size_t len;
Fiber->recv_data(&data, &len);
printf("read data: %s ", data);
Fiber->yield("writer");
Sleep(100);
i++;
if(i == 5)
{
Fiber->end();
}
}
}
void __stdcall Fiber_Writer(LPVOID lpFiberParameter)
{
CFiber* Fiber = (CFiber*)lpFiberParameter;
while(1)
{
Fiber->send_data((void*)"hello from writer!!", strlen("hello from writer!!"));
Fiber->yield("reader");
Sleep(100);
}
}
int __cdecl _tmain(int argc, TCHAR *argv[])
{
{
CFiberFactory FiberFactory;
CFiber* reader = FiberFactory.AddFilber("reader", Fiber_Reader);
CFiber* writer = FiberFactory.AddFilber("writer", Fiber_Writer);
FiberFactory.yield("writer");
printf("--- ---- ----- ");
}
return 0;
}