在 MinGW 下使用 C++ 标准线程库
2010-06-30 08:03
295 查看
MinGW 已经支持 gcc 4.5 了,它是目前支持 C++0x最完整的编译器了。我用它成功的写了些自己好玩的项目。
不过这个发行版并不完整支持 gcc 的 C++ 标准线程库,看了些资料,要修改一下它带的 C++ 标准库代码,重编译就可以。研究了一天,终于搞定了,主要参考了这篇文章,但是也还是要有些改动。记录一下。
首先是环境,gcc 4.5用的 C++ 库是 libstdc++ v3,这个库的完整代码包含在 gcc 代码里,去 GNU 下载一份 gcc 4.5 的代码,把 libstdc++ 拿出来即可。
其次 libstdc++ 的线程是基于 pthread 的,在 Windows 下面现在有几种办法使用 pthread:一是 pthread-win32 库,这是个开源的 pthread 实现,很幸运 MinGW 发行版里面已经带了这个库;另一个可能的办法是微软自家的 Subsystem for Unix-based Applications (SUA),它在 Windows 7 Ultimate 和 Windows Server 2008 R2 上面是可选装的 Windows 组件,我还没有尝试,以后有空玩玩。
然后是修改代码和编译:
修改 MinGW/lib/gcc/mingw32/4.5.0/include/c++/mingw32/bits/error_constants.h
里面的 operation_not_permitted = EPERM 这一行被注释掉了,取消注释
pthread 中最重要的数据结构:线程标识 pthread_t,在 pthread-win32 下面是一个 struct,而 libstdc++ 假定它可以比较大小,这样编译会出错,所以要在 MinGW/include/pthread.h 里 pthread_t 定义之后加上一段:
inline bool operator<(pthread_t left, pthread_t right)
{
return left.p < right.p;
}
这个比较当然很不严谨,不过够用了。
MinGW 在编译 libstdc++ 的时候,由于相应的编译开关没打开,所以以下四个文件的内容没编译进去,从 libstdc++ 里面拷出这四个文件来,准备自己编译:mutex.cc, atomic.cc, conditional_variable.cc, thread.cc
文件 atomic.cc 的第一行是
#include “gstdint.h”
这个文件并不存在,其实这个文件原本应该由配置工具生成,用来控制包含的整数类型,我就自己人肉生成一个 gstdint.h,只要一行:
#include <stdint.h>
把它和 atomic.cc 放在同一个目录下
编译前最后一步,加上必要的宏定义,我尝试下来,最小集合似乎是
#define _GLIBCXX__PTHREADS
#define _GLIBCXX_HAS_GTHREADS
#define _POSIX_TIMEOUTS=1
这几个既可以加在代码里,也可以加在编译器开关里,我用 Code::Blocks ,于是也可以加在 IDE 选项里
之后用 MinGW 把这四个文件编译成 library,然后在自己的代码里链接到它就行了。我参考的文章里建议用 ar 把编译的 .o 文件加到 libstdc++.a 里面,这也是个办法。
不过这个发行版并不完整支持 gcc 的 C++ 标准线程库,看了些资料,要修改一下它带的 C++ 标准库代码,重编译就可以。研究了一天,终于搞定了,主要参考了这篇文章,但是也还是要有些改动。记录一下。
首先是环境,gcc 4.5用的 C++ 库是 libstdc++ v3,这个库的完整代码包含在 gcc 代码里,去 GNU 下载一份 gcc 4.5 的代码,把 libstdc++ 拿出来即可。
其次 libstdc++ 的线程是基于 pthread 的,在 Windows 下面现在有几种办法使用 pthread:一是 pthread-win32 库,这是个开源的 pthread 实现,很幸运 MinGW 发行版里面已经带了这个库;另一个可能的办法是微软自家的 Subsystem for Unix-based Applications (SUA),它在 Windows 7 Ultimate 和 Windows Server 2008 R2 上面是可选装的 Windows 组件,我还没有尝试,以后有空玩玩。
然后是修改代码和编译:
修改 MinGW/lib/gcc/mingw32/4.5.0/include/c++/mingw32/bits/error_constants.h
里面的 operation_not_permitted = EPERM 这一行被注释掉了,取消注释
pthread 中最重要的数据结构:线程标识 pthread_t,在 pthread-win32 下面是一个 struct,而 libstdc++ 假定它可以比较大小,这样编译会出错,所以要在 MinGW/include/pthread.h 里 pthread_t 定义之后加上一段:
inline bool operator<(pthread_t left, pthread_t right)
{
return left.p < right.p;
}
这个比较当然很不严谨,不过够用了。
MinGW 在编译 libstdc++ 的时候,由于相应的编译开关没打开,所以以下四个文件的内容没编译进去,从 libstdc++ 里面拷出这四个文件来,准备自己编译:mutex.cc, atomic.cc, conditional_variable.cc, thread.cc
文件 atomic.cc 的第一行是
#include “gstdint.h”
这个文件并不存在,其实这个文件原本应该由配置工具生成,用来控制包含的整数类型,我就自己人肉生成一个 gstdint.h,只要一行:
#include <stdint.h>
把它和 atomic.cc 放在同一个目录下
编译前最后一步,加上必要的宏定义,我尝试下来,最小集合似乎是
#define _GLIBCXX__PTHREADS
#define _GLIBCXX_HAS_GTHREADS
#define _POSIX_TIMEOUTS=1
这几个既可以加在代码里,也可以加在编译器开关里,我用 Code::Blocks ,于是也可以加在 IDE 选项里
之后用 MinGW 把这四个文件编译成 library,然后在自己的代码里链接到它就行了。我参考的文章里建议用 ar 把编译的 .o 文件加到 libstdc++.a 里面,这也是个办法。
相关文章推荐
- 为什么在C++使用pthread_create()的时候,类成员函数做线程的处理函数必须要定义成static类型的?
- 注意使用vc的标准c/c++库的不同版本
- Windows下Eclipse进行C/C++开发——Eclipse+CDT+MinGW的配置与使用详解
- 使用C/C++运行时库函数操作线程
- 使用标准C++的类型转换符:static_cast、dynamic_cast、reinterpret_cast、和const_cast
- [并发并行]_[C/C++]_[C++标准库里的线程安全问题]
- 【转贴】使用标准C++的类型转换符:static_cast、dynamic_cast、reinterpret_cast、和const_cast
- C++标准支持从宽字符到UTF8的转换(避免使用WINAPI函数)
- 使用标准C++的类型转换符:static_cast、dynamic_cast、reinterdivt_cast、和const_cast
- Mac上使用C++ 11标准编译程序
- C++ 标准输入 cin 使用
- [MinGW]_[C/C++]_[msys的使用问题]
- 标准C++中的String类的使用
- Java使用Eclipse_cdt和MinGw编写C++/java,jni的小例子
- 使用eclipse(v3.01)与mingw(v3.1.0)搭建Windows下C/C++开发环境
- 标准C++与线程
- 在Windows下使用Eclipse + CDT+MinGW开发C/C++程序
- C/C++ 跨平台交叉编译、静态库/动态库编译、MinGW、Cygwin、CodeBlocks使用原理及链接参数选项
- 关注C++细节---C++11新标准之decltype的使用注意
- [JNI] Eclipse直接完成JAVA调用C/C++ (Eclipse上使用CDT结合MinGW)