分享
 
 
 

修改BOOST(一)

王朝other·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

修改BOOST(一)

boost是个不错的库。可是也不算太成熟。例如,boost的处理TLS是通过boost_threadmon.dll,使用了TLS的代码必须带一个动态链接库;其次库也不能自动安装,也不能根据你的程序选择了什么样的链接方式(如MT,MD)选择库,如果每次编写一个小型的测试程序都要设置很多东西,恐怕太费力气了;第三,缺乏一些常用的功能,如事件,读写锁等。今天我要设置的是使得你在VC下只需要设置MT或MD方式(链接到多线程动态链接和静态连接库)就可以使用boost。其次是将boost_threadmon.dll合并到libboost_thread.lib库中。『本人刚学boost才4天,说错了恐怕在所难免,请指正。本文中使用的版本为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_handler的map中。cleanup_info第一个成员为清理函数指针,第二个成员为数据指针本身。而cleanup_handler则以TLS索引为key,以cleanup_info为data项内部的一个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的工程时,再也不需要任何设置了。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有