windows平台下编译zThread库

      今天看到《c++编程思想》中并发一章,作者使用zThread这个开源库来讲解,于是我也下了个版本编译,并简单使用了下,以下是具体步骤:

 一、创建工程

      1.下载源码

       由于官网http://zthread.sourceforge.net一直上不去,所以我从http://download.chinaunix.net/download.php?id=24079&ResourceID=12264下载了ZThread-2.3.1版本压缩包。解压后,只需关注include和src目录下的代码,src中还有好多平台相关的代码,放在各在平台名称命名的目录下,如linux、macos、solaris、win9x、win32。

      2.创建工程

      打开vs2010,创建一个windows console的空项目命名为zthread,工程目录中就产生一个D:\My Documents\Visual Studio 2010\Projects\zthread文件夹,接下去就是把需要的文件或目录拷贝到该目录下

      3.将解压包中相关代码拷贝到zthread的工程目录下,注意不要破环原先的目录结构

      首先只需拷贝include中文件,该目录中有库需要的头文件,include中只有一个zthread文件夹,所以将整个文件夹拷贝到工程目录 中,拷贝完成后在vs解决方案资源管理器中的头文件目录下新建一个删选器命名为zthread(删选器是一个逻辑目录,不会在磁盘中产生相应目录),这是为了使逻辑目录与磁盘中目录结构保持一致,便于代码管理,然后将刚才拷贝的目录中的所有头文件添加到该删选器下。

      接下来的步骤类似,还需拷贝src目录下的所有文件(不包含文件夹)和win32文件夹到工程目录下,然后添加拷贝的文件到工程中,如果文件在win32文件夹中,需要在vs中创建响应删选器再添加文件。

       4.创建一个cpp文件,写一个简单main函数。然后开始编译。

 

二、解决编译问题

       编译过程中大概会出现几类错误:

       1.打不开包含的文件

            (1).如果需要的文件未添加工程,则按步骤3方式添加,之后根据编译错误还添加了posix和vanilla两个目录到工程中

            (2).如果文件已经添加到了工程中,则查看include的相对路径是否正确

       2.无法打开pthread.h

              这个文件是posix thread中的,不在zthread包中,所以需要下载,下载路径 ftp://sourceware.org/pub/pthreads-win32/dll-latest,只需下载windows平台下的lib、dll和三个头文件,头文件分别是pthread.h, sched.h, semaphore.h,下载之后在工程目录下创建bin和lib目录,分别存放dll和lib,把3个头文件直接拷贝到工程目录下

       3.程序中对pthread_t结构体使用错误

               pthread_t结构体定义

                typedef struct {
                       void * p;                   /* Pointer to actual object */
                       unsigned int x;             /* Extra information - reuse count etc */
               } ptw32_handle_t;

            typedef ptw32_handle_t pthread_t;

 程序中有几处直接对该类型对象用0初始化或者和0进行==和!=的比较,所以要稍加修改,为了不修改pthread.h 中该结构体的定义,所以自己要写个额外的类

#pragma once
#include "pthread.h"

class ThreadId
{
public:
ThreadId(const pthread_t& tid)
: tid(tid)
{

}

bool operator==(const pthread_t& tidr)const
{
return tid.p == tidr.p && tid.x == tidr.x;
}

bool operator!=(const pthread_t& tidr)const
{
return !(operator==(tidr));
}

const static pthread_t UNINIT_THREAD_ID;
private:
const pthread_t& tid;
};

const pthread_t ThreadId::UNINIT_THREAD_ID = {NULL, 0};
//使用时将ops->_tid == 0改为ThreadId(ops->_tid) == ThreadId::UNINIT_THREAD_ID
//用ThreadId::UNINIT_THREAD_ID来初始化pthread_t类型对象

 

          4.链接错误

           (1).移除 AtomicCount类的两个实现文件,一个在工程目录下,一个咋win32目录下

            因为工程目录下的AtomicCount.cxx代码如下,与平台相关的条件编译在下载的源码中已经被注释,直接包含了#  include "vanilla/SimpleAtomicCount.cxx",所以AtomicCount的实现文件只留vanilla目录下的SimpleAtomicCount.cxx,其他两个都移除,还有一个在win32目录下,该目录下的实现文件不全,没有实现++,--的前置和后置操作符

#ifndef __ZTATOMICCOUNTSELECT_H__
#define __ZTATOMICCOUNTSELECT_H__

#include "zthread/AtomicCount.h"
#include "zthread/Config.h"

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif


 Select the correct AtomicCount implementation based on
 what the compilation environment has defined
//
//#if defined(HAVE_ATOMIC_LINUX)
//#  include "linux/AtomicCount.cxx"
//#elif defined(ZT_WIN32)
//#  include "win32/AtomicCount.cxx"
//#elif defined(ZT_WIN9X)
//#  include "win9x/AtomicCount.cxx"
//#endif
//
 Default to an AtomicCount that just uses a FastLock
//#ifndef __ZTATOMICCOUNTIMPL_H__
//#  include "vanilla/SimpleAtomicCount.cxx"
//#endif


#  include "vanilla/SimpleAtomicCount.cxx"

#endif // __ZTATOMICCOUNTSELECT_H__


             (2).错误2中下载的lib没有在工程属性中指定

               需要指定lib路径,并在链接输入相中添加lib名称

       

 

三、简单测试

以上问题解决后基本可以通过编译,编译完成后还需要将错误2中保存在bin目录下的dll拷贝到exe的目录下,程序才能运行。

程序成功运行后可在main函数中加入测试代码,先写个测试类LiftOff

#pragma once
#include <iostream>
#include "zthread/Runnable.h"

class LiftOff : public ZThread::Runnable
{
public:
	LiftOff(int nCountDown, int nId = 0)
		: m_nCountDown(nCountDown)
		, m_nId(nId)
	{

	}

	~LiftOff()
	{
		std::cout<<m_nId<<" completed\n";
	}

	virtual void run()
	{
		while(m_nCountDown--)
		{
			std::cout<<m_nId<<":"<<m_nCountDown<<std::endl;
			//Thread::yield();
		}
		std::cout<<"liftoff\n";
	}

private:
	int m_nCountDown;
	int m_nId;
};


在main函数中测试

#include "LiftOff.h"
#include "zthread/Thread.h"
using namespace ZThread;
int main()
{
	try
	{
		Thread t(new LiftOff(10));
		std::cout<<"wait\n";
	}
	catch (Synchronization_Exception& e)
	{
		std::cout<<e.what()<<std::endl;
	}

	Thread::sleep(5000);
	return 0;
}


 


 新增:在vs2010中编译通过的zthread lib工程已上传

 引申:在linux中使用zthread库发生编译错误,错误如下:


/home/scx/workspace/FsMonitor/Common/Thread/zthread/Guard.h:494:20: note: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of an undeclared name is deprecated)
make: *** [Common/Thread/zthread/vanilla/SimpleAtomicCount.o] Error 1


  其中有个模板继承的概念,错误原因解释:http://blog.csdn.net/ddl007/article/details/6059580,可以通过设置-fpermissive选项来解决。

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值