linux C++ 多线程编程
生活随笔
收集整理的這篇文章主要介紹了
linux C++ 多线程编程
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
http://blog.chinaunix.net/uid-14880649-id-2954431.html
1.Solaris .vs. Linux Posix 庫
如何在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);
}
?其他參考網頁
?http://www.ibm.com/developerworks/cn/linux/l-cn-mthreadps/index.html
?http://www.cppblog.com/bigsml/archive/2006/09/07/12137.html
| 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() | 寫非阻塞讀/寫鎖上的鎖。 |
總結
以上是生活随笔為你收集整理的linux C++ 多线程编程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 看django视频笔记
- 下一篇: 今天写的一个makefile,备份下