windows下使用pthread庫

來源:互聯網
上載者:User

最近在看《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,就可以得到這個開源庫了。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.