Linux C++ 多線程編程


1.Solaris .vs. Linux Posix 庫函數

 

Solaris 庫(lib 線程) Linux POSIX 庫(libp 線程) 操作
sema_destroy() sem_destroy() 銷毀信號狀態。
sema_init() sem_init() 初始化信號。
sema_post() sem_post() 增加信號。
sema_wait() sem_wait() 阻止信號計數。
sema_trywait() sem_trywait() 減少信號計數。
mutex_destroy() pthread_mutex_destroy() 銷毀或禁用與互斥對象相關的狀態。
mutex_init() pthread_mutex_init() 初始化互斥變量。
mutex_lock() pthread_mutex_lock() 鎖定互斥對象和塊,直到互斥對象被釋放。
mutex_unlock() pthread_mutex_unlock() 釋放互斥對象。
cond_broadcast() pthread_cond_broadcast() 解除對等待條件變量的所有線程的阻塞。
cond_destroy() pthread_cond_destroy() 銷毀與條件變量相關的任何狀態。
cond_init() pthread_cond_init() 初始化條件變量。
cond_signal() pthread_cond_signal() 解除等待條件變量的下一個線程的阻塞。
cond_wait() pthread_cond_wait() 阻止條件變量,並在最后釋放它。
rwlock_init() pthread_rwlock_init() 初始化讀/寫鎖。
rwlock_destroy() pthread_rwlock_destroy() 鎖定讀/寫鎖。
rw_rdlock() pthread_rwlock_rdlock() 讀取讀/寫鎖上的鎖。
rw_wrlock() pthread_rwlock_wrlock() 寫讀/寫鎖上的鎖。
rw_unlock() pthread_rwlock_unlock() 解除讀/寫鎖。
rw_tryrdlock() pthread_rwlock_tryrdlock() 讀取非阻塞讀/寫鎖上的鎖。
rw_trywrlock() pthread_rwlock_trywrlock() 寫非阻塞讀/寫鎖上的鎖。

 http://fanqiang.chinaunix.net/a4/b8/20010811/0905001105.html

http://blog.csdn.net/meteor1516/archive/2008/05/07/2409705.aspx

如何在linux 下c++中類的成員函數中創建多線程
 
linux系統中線程程序庫是POSIX pthread。POSIX pthread它是一個c的庫,用C語言進行多線程編程我這里就不多說了,網上的例子很多。但是如何在C++的類中實現多線程編程呢?如果套用C語言中創建多線程的方式,在編譯的時候會出現...does not match `void*(*)(void*)..這樣的錯誤。出現這種情況的原因是,編譯器在處理C++和C文件上是不同的,也就是說C++和C語言里邊指針函數不等價。解決這種錯誤的方法
 
有兩種:
1、不要將線程函數定義為類的成員函數,但是在類的成員函數里邊調用它。
例如:
[test.h]
#ifndef TEST_H
#define TEST_H
 
class test
{
public:
    test();
    ~test();
private:
    void createThread();
};
 
#endif
 
[test.cpp]
test::test()
{}
test::~test()
{}
 
void *threadFunction()
{
    printf("This is a thread");
 
    for(;;);
}
 
void test::createThread()
{
    pthread_t threadID;
 
    pthread_create(&threadID, NULL, threadFunction, NULL);
}
 
[main.cpp]
 
#inlcude "test.h"
 
int main()
{
    test t;
    t.createThead();
 
    for(;;);
 
    return 0;
}
 
2、將線程函數作為類的成員函數,那么必須聲明改線程函數為靜態的函數,並且該線程函數所引用的其他成員函數也必須是靜態的,如果要使用類的成員變量,則必須在創建線程的時候通過void *指針進行傳遞。
例如:
【test.h】
#ifndef TEST_H
#define TEST_H
 
class test
{
public:
    test();
    ~test();
private:
    int p;
    static void *threadFction(void *arg);
    static void sayHello(int r);
    void createThread();
};
 
#endif
 
[test.cpp]
test::test()
{}
test::~test()
{}
 
void *test::threadFunction(void *arg)
{
    int m = *(int *)arg;
    sayHello(m);
 
    for(;;);
}
 
void sayHello(int r)
{
    printf("Hello world %d!\n", r);
}
void test::createThread()
{
    pthread_t threadID;
 
    pthread_create(&threadID, NULL, threadFunction, NULL);
}
 
[main.cpp]
 
#inlcude "test.h"
 
int main()
{
    test t;
    t.createThead();
 
    for(;;);
 
    return 0;
}
====================================================================================

 http://bigbossman.blogbus.com/logs/10761605.html

 Linux下的編程一直是C語言的天下,但老是用C感覺寫的很乏味。用面向對象方法編程,聽着都倍有面子。於是決定先在的這個項目用C++來寫。雖然不一定能“以C++的思想”來寫C++,少會有C++的樣子。


但是問題來了:我需要在程序中動態創建一個線程,而pthread不接受C++類的成員函數作為參數。

原因也很簡單,類成員是在類被實例化成為對象后才存在的,即在編譯時是不存在的,編譯器無法取得函數的確切入口地址,自然無法通過編譯。

照這個分析,如果把要調用的類成員函數聲明為靜態的,pthread_create就可以找到函數的地址了。但這樣一來的話,由於類中的靜態函數無法調用類的非靜態成員。線程函數的功能就受到了很大限制,也就沒有比要將其放在類中了。

最容易想到的解決方案就是寫個C函數,然后再C函數中調用C++對象的成員函數。

比如類為

class foo(){

    public :
        thread();

}

class *f;

void *bar(void *arg){

    f->thread();       

    return NULL;
}

int  main(){

    .........
    f=new foo();
    
    pthread_create(&tid,&tattr,bar,NULL);

}

顯然這種發法太笨了,而且對象只能是全局的。

注意到線程函數bar可以有一個任意類型的指針作為參數,那我們何不將對象通過這個指針將對象變為bar的一個參數,從而讓我們的程序好看一些。

class foo(){

    public :
        thread();

}


void *bar(void *args){

    foo *f=(foo *)args;

    f.thread();       

    return NULL;
}

int  main(){

    .........
    foo *f=new foo();
    pthread_create(&tid,&tattr,bar,f);

}

如果把上述兩種方法結合起來即對象中的靜態函數+通過指針參數傳遞對象,那又會怎么樣呢?

class foo(){

    public :
        int thread();

        static void *wrapper(void *args){
            foo *f=static_cast<foo *>(args);
            f->thread();
            return NULL;
        }

}


int  main(){

    .........
    foo *f=new foo();
    pthread_create(&tid,&tattr,foo::wrapper,&f);

}

這樣就比較規整了吧?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM