修改BOOST(一)

 

修改BOOST()

 

    boost是个不错的库。可是也不算太成熟。例如,boost的处理TLS是通过boost_threadmon.dll,使用了TLS的代码必须带一个动态链接库;其次库也不能自动安装,也不能根据你的程序选择了什么样的链接方式(MT,MD)选择库,如果每次编写一个小型的测试程序都要设置很多东西,恐怕太费力气了;第三,缺乏一些常用的功能,如事件,读写锁等。今天我要设置的是使得你在VC下只需要设置MTMD方式(链接到多线程动态链接和静态连接库)就可以使用boost。其次是将boost_threadmon.dll合并到libboost_thread.lib库中。『本人刚学boost4天,说错了恐怕在所难免,请指正。本文中使用的版本为1.28.0

 

boost多线程库包括两个,一个是boost_threadmon.dll,是个动态连接库,另一个为libboost_thread.lib,是个静态链接库。为什么要用两个呢?主要是为了清除TLS中的数据。在boost_threadmon.dll加载的时候,动态链接库收到消息DLL_PROCESS_ATTACH,这时它分配一个TLS和关键代码段CriticalSection。在用户程序创建线程的时候,收到DLL_THREAD_ATTACH,这时将该线程的TLS数据清除。当主程序退出的时候,收到DLL_PROCESS_DETACH,这时动态链接库清除主线程的TLS数据。

 

Boost管理TLS如下:当用户设置TLS数据时,boost将该数据指针和一个清理函数放置到一个cleanup_info的结构中,并将它设置到一个cleanup_handlermap中。cleanup_info第一个成员为清理函数指针,第二个成员为数据指针本身。而cleanup_handler则以TLS索引为key,以cleanup_infodata项内部的一个TLS索引对应着一个cleanup_handlers指针,而该指针中的数据都是用户分配的TLS和对应的数据指针以及释放函数。Boost又使用on_thread_exit(&cleanup)函数将cleanup_handlers安装到boost_threadmon.dll中的TLS索引上。

涉及的tss.cpp中的结构如下:

 

    typedef std::pair<void(*)(void*), void*> cleanup_info;

    typedef std::map<int, cleanup_info> cleanup_handlers;

 

涉及的threadmon.cpp中的结构如下:

typedef void (__cdecl * handler)(void);

typedef std::list<handler> exit_handlers;

typedef std::set<exit_handlers*> registered_handlers;

 

上面可能我根本没有说清楚,可是我不想再打太多的字了,下面直接修改:

1. Thread.hpp文件开头修改为:

#ifndef BOOST_THREAD_WEK070601_HPP

#define BOOST_THREAD_WEK070601_HPP

/*

·monitor库:使用/MT       boost_mon_libmt.lib        thread:boost_thread_libmt.lib

·monitor库:使用/MTD       boost_mon_libmtd.lib       thread:boost_thread_libmtd.lib

·monitor库:使用/MD       boost_mon_libmd.lib       thread:boost_thread_libmd.lib

·monitor库:使用/MDD   boost_mon_libmdd.lib       thread:boost_thread_libmdd.lib

 

·monitor-thread合并库:使用/MT              boost_thread_mon_libmt.lib       

·monitor-thread合并库:使用/MTD       boost_thread_mon_libmtd.lib    

·monitor-thread合并库:使用/MD              boost_thread_mon_libmd.lib

·monitor-thread合并库:使用/MDD          boost_thread_mon_libmdd.lib    

*/

 

#ifdef WIN32

       #ifndef  _MT

              #error ERROR: Must compiled with multithread dll!

       #endif

 

       #define BOOST_HAS_THREADS

       #ifndef BOOST_THREADMON_AS_DLL

              #ifdef _DEBUG

                     #ifdef _DLL

                            #pragma comment( lib, "boost_thread_mon_libmdd.lib")

                     #else

                            #pragma comment( lib, "boost_thread_mon_libmtd.lib")

                     #endif

              #else

                     #ifdef _DLL

                            #pragma comment( lib, "boost_thread_mon_libmd.lib")

                     #else

                            #pragma comment( lib, "boost_thread_mon_libmt.lib")

                     #endif

              #endif

       #else

              #ifdef _DEBUG

                     #ifdef _DLL

                            #pragma comment( lib, "boost_mon_libmdd.lib")

                            #pragma comment( lib, "boost_thread_libmdd.lib")

                     #else

                            #pragma comment( lib, "boost_mon_libmtd.lib")

                            #pragma comment( lib, "boost_thread_libmtd.lib")

                     #endif

              #else

                     #ifdef _DLL

                            #pragma comment( lib, "boost_mon_libmd.lib")

                            #pragma comment( lib, "boost_thread_libmd.lib")

                     #else

                            #pragma comment( lib, "boost_mon_libmt.lib")

                            #pragma comment( lib, "boost_thread_libmt.lib")

                     #endif

              #endif

       #endif

#endif

//

 

#include <boost/config.hpp>

#ifndef BOOST_HAS_THREADS

#   error   Thread support is unavailable!

#endif

 

2. Threadmon.hpp文件修改为:

///

//2002.5.30修改。

#ifdef BOOST_THREADMON_AS_DLL

       #ifdef BOOST_THREADMON_EXPORTS

              #define BOOST_THREADMON_API __declspec(dllexport)

       #else

              #define BOOST_THREADMON_API __declspec(dllimport)

       #endif

#else

       #define BOOST_THREADMON_API 

#endif

 

 

extern "C" BOOST_THREADMON_API int on_thread_exit(void (__cdecl * func)(void));

extern "C" BOOST_THREADMON_API void on_thread_detach();

 

3. Threadmon.cpp文件修改为:

///

//This File has been modified!

// threadmon.cpp : Defines the entry point for the DLL application.

//

//2002.5.30.modified.

#ifdef BOOST_THREADMON_AS_DLL

#define BOOST_THREADMON_EXPORTS

#else

#include <boost/thread/once.hpp>

#endif//BOOST_THREADMON_AS_DLL

 

#include "threadmon.hpp"

 

 

#ifdef BOOST_HAS_WINTHREADS

 

#define WIN32_LEAN_AND_MEAN     // Exclude rarely-used stuff from Windows headers

#include <windows.h>

 

#ifdef BOOST_MSVC

#   pragma warning(disable : 4786)

#endif

 

#include <list>

#include <set>

#include <algorithm>

 

typedef void (__cdecl * handler)(void);

typedef std::list<handler> exit_handlers;

typedef std::set<exit_handlers*> registered_handlers;

 

namespace

{

    CRITICAL_SECTION cs;

    DWORD key;

    registered_handlers registry;

}

 

 

void on_process_attach()

{

InitializeCriticalSection(&cs);

key = TlsAlloc();

}

 

 

void on_process_detach()

{

on_thread_detach();

    // Destroy any remaining exit handlers.  Above we assumed there'd only be the main

    // thread left, but to insure we don't get memory leaks we won't make that assumption

    // here.

    EnterCriticalSection(&cs);

    for (registered_handlers::iterator it = registry.begin();

it != registry.end(); ++it)

{

#ifndef BOOST_THREADMON_AS_DLL

        for (exit_handlers::iterator p = (*it)->begin(); p != (*it)->end(); ++p)

            (*p)();

#endif

        delete (*it);

}

    LeaveCriticalSection(&cs);

    DeleteCriticalSection(&cs);

    TlsFree(key);

}

 

 

#ifdef BOOST_THREADMON_AS_DLL

 

 

#if defined(__BORLANDC__)

#define DllMain DllEntryPoint

#endif

 

extern "C"

BOOL WINAPI DllMain(HANDLE module, DWORD reason, LPVOID)

{

    switch (reason)

    {

        case DLL_PROCESS_ATTACH:

        on_process_attach();

            break;

        case DLL_THREAD_ATTACH:

            break;

        case DLL_THREAD_DETACH:

        on_thread_detach();

            break;

        case DLL_PROCESS_DETACH:

        on_process_detach();

            break;

    }

    return TRUE;

}

 

#else//BOOST_THREADMON_AS_DLL

 

boost::once_flag once = BOOST_ONCE_INIT;

 

class process_envelope

{

process_envelope()

{

boost::call_once(&on_process_attach, once);

}

public:

~process_envelope(){on_process_detach();}

static process_envelope *get()

{

static process_envelope p;

return &p;

}

};

 

#endif//!BOOST_THREADMON_AS_DLL

 

void on_thread_detach()

{

    // Call the thread's exit handlers.

#ifndef BOOST_THREADMON_AS_DLL

process_envelope::get();

#endif

    exit_handlers* handlers = static_cast<exit_handlers*>(TlsGetValue(key));

    if (handlers)

    {

        for (exit_handlers::iterator it = handlers->begin(); it != handlers->end(); ++it)

            (*it)();

 

        // Remove the exit handler list from the registered lists and then destroy it.

        EnterCriticalSection(&cs);

        registry.erase(handlers);

        LeaveCriticalSection(&cs);

        delete handlers;

    }

}

 

int on_thread_exit(void (__cdecl * func)(void))

{

#ifndef BOOST_THREADMON_AS_DLL

process_envelope::get();

#endif

    // Get the exit handlers for the current thread, creating and registering

    // one if it doesn't exist.

    exit_handlers* handlers = static_cast<exit_handlers*>(TlsGetValue(key));

    if (!handlers)

    {

        try

        {

            handlers = new exit_handlers;

            // Handle "broken" implementations of operator new that don't throw.

            if (!handlers)

                return -1;

        }

        catch (...)

        {

            return -1;

        }

 

        // Attempt to set a TLS value for the new handlers.

        if (!TlsSetValue(key, handlers))

        {

            delete handlers;

            return -1;

        }

 

        // Attempt to register this new handler so that memory can be properly

        // cleaned up.

        try

        {

            EnterCriticalSection(&cs);

            registry.insert(handlers);

            LeaveCriticalSection(&cs);

        }

        catch (...)

        {

            LeaveCriticalSection(&cs);

            delete handlers;

            return -1;

        }

    }

 

    // Attempt to add the handler to the list of exit handlers. If it's been previously

    // added just report success and exit.

    try

    {

        handlers->push_front(func);

    }

    catch (...)

    {

        return -1;

    }

 

    return 0;

}

 

#endif // BOOST_HAS_WINTHREADS

 

4. Thread.cpp文件修改为:

#include "timeconv.inl"行后:

//2002.5.30;修改

#ifdef WIN32

       #ifndef BOOST_THREADMON_AS_DLL

       #include "threadmon.hpp"

       #endif

#endif

 

              修改thread_proxy(void* param)方法的尾部为:

//2002.5.30;修改

#ifdef WIN32

       #ifndef BOOST_THREADMON_AS_DLL

       on_thread_detach();

       #endif

#endif

 

5. <boost>/libs/thread/src目录下的所有文件插入到自己新建的工程中,按上面的thread.hpp头文件中的库名分别生成不同的库文件,将这些库文件拷贝到VC目录下,以后编译使用了boost.thread的工程时,再也不需要任何设置了。

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Boost是一个流行的、开源的C++库集合,其中包含了许多实用的工具和组件,可以帮助我们更方便地开发高性能的网络应用程序。下面是一个使用Boost.Asio实现的简单的服务器框架: ```c++ #include <iostream> #include <boost/asio.hpp> using namespace boost::asio; using namespace boost::asio::ip; class Server { public: Server(int port) : acceptor_(io_service_, tcp::endpoint(tcp::v4(), port)) { start_accept(); io_service_.run(); } private: void start_accept() { TcpConnection::pointer new_connection = TcpConnection::create(io_service_); acceptor_.async_accept(new_connection->socket(), boost::bind(&Server::handle_accept, this, new_connection, boost::asio::placeholders::error)); } void handle_accept(TcpConnection::pointer new_connection, const boost::system::error_code& error) { if (!error) { new_connection->start(); } start_accept(); } io_service io_service_; tcp::acceptor acceptor_; }; class TcpConnection : public boost::enable_shared_from_this<TcpConnection> { public: typedef boost::shared_ptr<TcpConnection> pointer; static pointer create(io_service& io_service) { return pointer(new TcpConnection(io_service)); } tcp::socket& socket() { return socket_; } void start() { boost::asio::async_read(socket_, boost::asio::buffer(buffer_), boost::bind(&TcpConnection::handle_read, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } private: TcpConnection(io_service& io_service) : socket_(io_service) { } void handle_read(const boost::system::error_code& error, size_t bytes_transferred) { if (!error) { std::cout << "Received message from client: " << std::string(buffer_.data(), bytes_transferred) << std::endl; } } tcp::socket socket_; boost::array<char, 1024> buffer_; }; int main() { try { Server server(8080); } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << std::endl; } return 0; } ``` 在这个服务器框架中,我们使用Boost.Asio库来处理网络通信,其中io_service是一个关键的组件,它负责管理异步I/O操作的事件循环。在Server类中,我们首先创建一个tcp::acceptor对象,然后调用其async_accept函数来监听客户端的连接请求。当有新的连接请求到来时,我们创建一个TcpConnection对象,并调用其start函数来开始接收客户端发送的消息。TcpConnection类继承自boost::enable_shared_from_this,这样我们可以在异步回调函数中安全地使用shared_from_this来获取当前对象的智能指针,避免了可能的内存泄漏问题。 当客户端发送消息时,我们在TcpConnection类中定义了handle_read函数来处理接收到的数据。在这个简单的实现中,我们只是简单地将数据打印到控制台上,实际上我们可以在这里进行更复杂的业务逻辑处理。 以上是一个简单的使用Boost实现的服务器框架,您可以根据自己的需要进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值