异步机制 - 纤程编程

协程,其思想是,一系列互相依赖的协程间依次使用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\n", 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("--- ---- ----- \n");

    }

 

    return 0;

}

posted @ 2015-04-28 10:01  sysnap  阅读(289)  评论(0编辑  收藏  举报