`
xpp02
  • 浏览: 1013397 次
社区版块
存档分类
最新评论

windows下使用pthread库

 
阅读更多

最近在看《C++多核高级编程》这本书,收集了些有用的东西,方便在windows下使用POSIX标准进行Pthread开发,有利于跨平台。

--------------------------------------------------
windows下使用pthread库时间:2010-01-27 07:41来源:罗索工作室 作者:落鹤生 点击:1220次

我听很多人都说pthreads对Windows的兼容性不好,但我又没用过,也根本不知道到底好,还是不好,只不过我看ffmpeg都有在用pthreads,而做流媒体的话ffmpeg是必不可少的,那是否ffmpeg选错了,它该怎么搞一套类似pthreads的东西出来呢?问题是它没有。所以我想试试看。

1 下载库

建议大家下载:ftp://sources.redhat.com/pub/pthreads-win32/这个自解压文件,压缩包里的pthreads.2目录是源码,Pre-built.2目录是编译所需的头文件和库文件。

如果要自行编译请看这里:

使用微软的CL来编译:
rem cl.bat
cl.exe main.cpp /c /I"c:/pthreads-w32-2-7-0-release/Pre-built.2/include"
link.exe /out:main_cl.exe main.obj /LIBPATH:"c:/pthreads-w32-2-7-0-release/Pre-built.2/lib" pthreadVC2.lib
pause

或者使用GCC来编译:
rem gcc.bat
g++.exe -o main.o -c main.cpp -I"c:/pthreads-w32-2-7-0-release/Pre-built.2/include"
g++.exe -o main_gcc.exe main.o "c:/pthreads-w32-2-7-0-release/Pre-built.2/lib/libpthreadGC2.a"
pause

嘿嘿!开源就是好啊,跨平台实现得如此容易


2 vc的设置

添加执行库、目录、库文件的路径;

01.//main.cpp
02.#include <stdio.h>
03.#include <pthread.h>
04.#include <assert.h>
05.
06.void* Function_t(void* Param)
07.{
08. printf("我是线程! ");
09. pthread_t myid = pthread_self();
10. printf("线程ID=%d ", myid);
11. return NULL;
12.}
13.
14.int main()
15.{
16. pthread_t pid;
17. pthread_attr_t attr;
18. pthread_attr_init(&attr);
19. pthread_attr_setscope(&attr, PTHREAD_SCOPE_PROCESS);
20. pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
21. pthread_create(&pid, &attr, Function_t, NULL);
22. printf("======================================== ");
23. getchar();
24. pthread_attr_destroy(&attr);
25. return 1;
26.}
3 测试

编写程序,添加项目中库文件,编译运行即可。

2:在VC下使用POSIX标准的线程

POSIX下的很多东西我都很喜欢,其中就包括pthread。不过跟使用socket面临同样的问题,在Linux下调试程序并没有VC下方便。所以,希望在VC下可以pthread写东西,调试没有问题的话可以在各个平台下使用。

在网上找了一些资料,发现VC下使用pthread也是异常简单啊,呵呵,记录下来,备用~~~

有一个叫做POSIX Threads for Win32的项目,专门为win32开发了一个pthread的lib,利用它,可以很方便的在win32下实现pthread的应用。我这里使用到的是2.8.0版本的POSIX Threads for Win32,下载地址:将下载到的exe解压之后,会得到三个目录:

其中,Pre-built.2中是已经编译好的lib以及dll,同时包含了一些必要的头文件。将其中的include文件夹和lib文件夹 copy到VC的安装目录下,例如,我的是VC6.0的环境,默认安装,则,需要copy到:C:/Program Files/Microsoft Visual Studio/VC98

接着,在编程的时候,引入pthreadVC2.lib即可:

1: #pragma comment(lib, "pthreadVC2.lib")

剩下的步骤,就和Linux下一样了,尽情享用吧^_^

-------------------------------------

Windows中的pthread程序(2009-06-23 19:47:56)
转载

闲着没事做,找了点pthread-win32的资料看了看,写了个无聊的程序。pthread的使用倒没有什么,倒是注意到了两个细节问题:

1 在微软的编译器中,可以在头文件开始处加#pragma once,防止文件被包含两次。它与更通用的#ifdef稍微不同,仅用于微软的编译器,它防止一个物理文件被包含两次,却不能防止相同内容的不同文件被包含两次。当然,这不是问题,相同内容包含两次会出编译错误的。

2 在多线程程序中,应该使用多线程的C运行时库。有两种方法来实现:

(1)在工程设置对话框中,选择【C/C++】选项卡,再在【Use run-time library】下拉列表中选择多线程库

(2)使用预处理命令。我是摸索了一会儿才发现正确的方法的:

#pragma comment(linker,"/NODEFAULTLIB:libcd /DEFAULTLIB:libcmt")


#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <pthread.h>

#include "myheader.h"
#include "myheader.h"

#pragma comment(lib,"pthreadVSE2")
#pragma comment(linker,"/NODEFAULTLIB:libcd /DEFAULTLIB:libcmt")

#define THREAD_NUM 10

static pthread_cond_t g_cond;
static pthread_mutex_t g_mutex;
static int g_index_wakeup;
static int g_exit_count;

typedef struct
{
pthread_key_t key;
int index;
int num;
}THREAD_DATA;

static void destroy_key(void* p)
{
THREAD_DATA* p_data;
p_data = (THREAD_DATA*)p;
printf("### thread %2d destroy key ###/n",p_data->index);
free(p);
if (++g_exit_count == THREAD_NUM)
{
pthread_cond_broadcast(&g_cond);
}
}

static void* thread_proc(void* p)
{
THREAD_DATA* p_data;

p_data = (THREAD_DATA*)p;
if (0 != pthread_key_create(&(p_data->key),destroy_key)) return NULL;
pthread_setspecific(p_data->key,p_data);

srand(time(NULL)+(int)p);
p_data->num = rand();

while (1)
{
p_data = (THREAD_DATA*)pthread_getspecific(p_data->key);
pthread_mutex_lock(&g_mutex);
if (-100 == g_index_wakeup)
{
pthread_mutex_unlock(&g_mutex);
break;
}
else if (p_data->index == g_index_wakeup)
{
printf("thread %d: the num is %d now./n",p_data->index,p_data->num);
p_data->num += rand();
g_index_wakeup = -1;
pthread_cond_broadcast(&g_cond);
}
pthread_mutex_unlock(&g_mutex);
Sleep(50);
}
return NULL;
}

int main(int argc,char* argv[])
{
pthread_t pid;
pthread_attr_t attr;
THREAD_DATA* p_data;
int cur;

pthread_mutex_init(&g_mutex,NULL);
pthread_cond_init(&g_cond,NULL);
g_index_wakeup = -1;

pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
for(cur = 0; cur < THREAD_NUM; cur++)
{
p_data = (THREAD_DATA*)malloc(sizeof(THREAD_DATA));
p_data->index = cur + 1;
pthread_create(&pid,&attr,thread_proc,p_data);
}
pthread_attr_destroy(&attr);

srand(time(NULL));
cur = 0;
while(1)
{
pthread_mutex_lock(&g_mutex);
if (-1 != g_index_wakeup)
{
pthread_cond_wait(&g_cond,&g_mutex);
}
do
{
g_index_wakeup = rand()%THREAD_NUM+1;
} while ((g_index_wakeup < 0) || (g_index_wakeup > THREAD_NUM));
if (++cur > THREAD_NUM)
{
g_exit_count = 0;
g_index_wakeup = -100;
printf("/n/n");
pthread_cond_wait(&g_cond,&g_mutex);
pthread_mutex_unlock(&g_mutex);
break;
}
else
{
printf("/n### Wake up thread %d ###/n",g_index_wakeup);
pthread_mutex_unlock(&g_mutex);
}
}

pthread_mutex_destroy(&g_mutex);
pthread_cond_destroy(&g_cond);

return 0;
}

---------------------------------------------------------------------------------

error LNK2005: xxx already defined in libcmt.lib(xxx.obj) MSVCRT.lib
参考:

这个错误是微软设计错误,因此如果遇到这个错误,我们只能躲过这个链接错误。具体的办法就是将那个提示出错的库放到另外一个库的前面。另外选择不同的C函数库,可能会引起这个错误。MS, C有两种C函数库,一种是普通的函数库:LIBC.LIB,不支持多线程。另外一种是支持多线程的:msvcrt.lib。如果一个工程里,这两种函数库混合使用,可能会引起这个错误。因此建议使用支持多线程的msvcrt.lib。

需要注意的是,当使用其他的库的时候最容易产生这种错误,例如boost和wxWindow使用/MD来编译的,也就是使用支持多线程的C函数库。这时候如果自己的程序没有指明/MD的话,就会提示两种C函数冲突,并且还有LNK2005错误。因此如果使用boost,wxWindow的话,需要指明/MD。

msvcrt.lib是VC中的Multithreaded DLL 版本的C运行时库,而libcmt.lib是Multithreaded的运行时库。在同一个项目中,所有的源文件必须链接相同的C运行时库。如果某一文件用了Multithreaded DLL版本,而其他文件用了Single-Threaded或者Multithreaded版本的库,也就是说用了不同的库,就会导致这个警告的出现。

VC中的C运行时库一共有6种
Single-threaded (libc.lib) libcmt.lib, msvcrt.lib, libcd.lib, libcmtd.lib, msvcrtd.lib
Multithreaded (libcmt.lib) libc.lib, msvcrt.lib, libcd.lib, libcmtd.lib, msvcrtd.lib
Multithreaded using DLL (msvcrt.lib) libc.lib, libcmt.lib, libcd.lib, libcmtd.lib, msvcrtd.lib
Debug Single-threaded (libcd.lib) libc.lib, libcmt.lib, msvcrt.lib, libcmtd.lib, msvcrtd.lib
Debug Multithreaded (libcmtd.lib) libc.lib, libcmt.lib, msvcrt.lib, libcd.lib, msvcrtd.lib
Debug Multithreaded using DLL (msvcrtd.lib) libc.lib, libcmt.lib, msvcrt.lib, libcd.lib, libcmtd.lib

这个在C++ ->Code Generation-->runtime library 中设置,实际上和静态dll和动态dll有关

解决办法:

Project Settings:
-> Configration Properties -> Linker -> Input -> Ignore Specific Library: libcmtd


libcmtd 这个库有时候不能忽略,忽略后会有不能解析的外部符号错误
其实有个方便的方法 链接时加入参数 /FORCE:MULTIPLE
-------------------------------------------------------------------------------------------

google一下POSIX Threads for Win32,就可以得到这个开源库了。


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics