pthread.h相関関数使用方法集錦のスレッド操作
6636 ワード
前言
pthread(POSIX thread)は、pthreadと略称され、スレッドのPOSIX規格であり、クラスUnixオペレーティングシステム(Unix、Linux、Mac OS Xなど)では、いずれもpthreadをオペレーティングシステムのスレッドとして用いている.そのプログラミング標準のヘッダファイルとして,本稿では,中の常用関数の意義と使用方法を検討する.
スレッド
pthread_create最初のパラメータはスレッド識別子を指すポインタであり、type: スレッド属性 を設定するための2番目のパラメータの3番目のパラメータはスレッド実行関数の開始アドレスであり、type: 4番目のパラメータは実行関数のパラメータで、type: パラメータなし関数
パラメータ関数
クラスメンバー関数
クラスメンバー関数を呼び出す方法は少し複雑で、別の関数パッケージが必要です.関数パラメータはクラスインスタンスポインタに明示的に入力され、その後、パラメータ付き関数を呼び出す方法と似ています.
pthread_join最初のパラメータはスレッド識別子、すなわちスレッドID、type: である.第2のパラメータretvalは、スレッドの戻り値を格納するためにユーザ定義ポインタであり、 .
pthread_detach
スレッドの作成のデフォルトのステータスは最初のパラメータはスレッド識別子、すなわちスレッドID、type: である.
ここでは
pthread_self
以上のコードは、メインスレッドとサブスレッドの異なるスレッドidを出力します.
pthread_onceの最初のパラメータは である.第2パラメータは無パラメータ関数ポインタ、type: 以下の例では、
出力:
pthread_cancel
pthread_kill
あるスレッドに信号を渡すには、作成したスレッドで最初のパラメータはスレッドマーカー、type: の2番目のパラメータはLinuxで定義された信号であり、type: テキストリンク
pthread(POSIX thread)は、pthreadと略称され、スレッドのPOSIX規格であり、クラスUnixオペレーティングシステム(Unix、Linux、Mac OS Xなど)では、いずれもpthreadをオペレーティングシステムのスレッドとして用いている.そのプログラミング標準のヘッダファイルとして,本稿では,中の常用関数の意義と使用方法を検討する.
スレッド
pthread_create
pthread_create
はUNIX環境作成スレッド関数です.合計4つのパラメータ:pthread_t*
(void*)(*)(void*)
void *
pthread_create
スレッドがパラメータ関数なしを実行するdemoを作成します.#include
#include
using namespace std;
// : void* (*)(void*)
void* test(void *ptr){
cout << "hello world." << endl;
}
int main()
{
pthread_t tid; // id typedef unsigned
pthread_create(&tid, NULL, test, NULL); //
pthread_join(tid, NULL);
}
パラメータ関数
pthread_create
は単一のポインタのみをサポートし、1つのパラメータしか送信できません.複数のパラメータを渡す場合は、構造体形式にカプセル化します.#include
#include
#include
using namespace std;
struct Param{
string name;
int age;
};
void* param_test(void* p){
Param *param = (Param*)p;
cout << "hello " << param->name << endl;
cout << "age = " << param->age << endl;
}
int main()
{
pthread_t tid;
Param *ptr = new Param();
ptr->name = "pthread";
ptr->age = 20;
pthread_create(&tid, NULL, param_test, ptr);
pthread_join(tid, NULL);
}
クラスメンバー関数
クラスメンバー関数を呼び出す方法は少し複雑で、別の関数パッケージが必要です.関数パラメータはクラスインスタンスポインタに明示的に入力され、その後、パラメータ付き関数を呼び出す方法と似ています.
#include
#include
#include
using namespace std;
class PthreadClass{
public:
void say_hello(){
cout << "hello world" << endl;
}
};
//
void* class_test(void *p){
PthreadClass *ptr = (PthreadClass*)p;
//
ptr->say_hello();
}
int main()
{
PthreadClass *ptr = new PthreadClass();
pthread_t tid;
pthread_create(&tid, NULL, class_test, ptr);
pthread_join(tid, NULL);
}
pthread_join
pthread_join
は、1つのスレッドの終了を待つために使用され、スレッド間で同期された動作、2つのパラメータがあります.pthread_t
type: void**
#include
#include
using namespace std;
class PthreadClass{
public:
void say_hello(){
cout << "hello world" << endl;
}
};
int retval = -1;
void* class_test(void *p){
PthreadClass *ptr = (PthreadClass*)p;
ptr->say_hello();
retval = 0;
return (void*)&retval;
}
int main()
{
PthreadClass *ptr = new PthreadClass();
pthread_t tid;
pthread_create(&tid, NULL, class_test, ptr);
/**
*
* , pthread_join,
*/
void *retval;
pthread_join(tid, &retval);
cout << *(int*)retval << endl;
}
pthread_detach
スレッドの作成のデフォルトのステータスは
joinable
です.スレッドが実行を終了してもjoinされていない場合、そのステータスはプロセス内のZombie Processに似ています.つまり、一部のリソースが回収されていない(ステータスコードを終了する)ので、スレッドの作成者はpthread_join
でスレッドの実行が終了するのを待って、スレッドの終了コードを得ることができます.リソースを回収します(wait,waitpidに似ています).しかし、pthread_join
を呼び出すと、スレッドが実行終了しない場合、呼び出し元がブロックされ、Webサーバでプライマリ・スレッドが新しく来たリンクごとにサブスレッドを作成して処理する場合、プライマリ・スレッドはpthread_を呼び出すことを望んでいない場合があります.joinでブロック(処理を継続してから来るリンクのため)すると、サブスレッドにコードpthread_datach
を追加してブロックから離脱することができ、このときサブスレッド状態はdetached
であり、実行終了後に自動的にリソースが解放される.pthread_detach
パラメータは1つのみです.pthread_t
#include
#include
#include
using namespace std;
void* test(void *p){
sleep(1000);
}
int main()
{
pthread_t tid;
pthread_create(&tid, NULL, test, NULL);
pthread_detach(tid);
for(int i = 0; i < 1000; i ++){
sleep(1);
cout << "sleep " << i << " second." << endl;
}
}
ここでは
pthread_detach
を使用するとtest
のsleep
内に詰まることなくfor
サイクルに入り、pthread_join
を使用するとtest
関数の実行が完了するまで待機します.pthread_self
pthread_self
関数にはパラメータがなく、現在のスレッドid
を取得する役割を果たします.
#include
#include
#include
using namespace std;
void* test(void *p){
cout << 'child thread: ' << pthread_self() << endl;
}
int main()
{
pthread_t tid;
pthread_create(&tid, NULL, test, NULL);
pthread_detach(tid);
cout << 'main thread: ' << pthread_self() << endl;
for(int i = 0; i < 1000; i ++){
sleep(1);
}
}
以上のコードは、メインスレッドとサブスレッドの異なるスレッドidを出力します.
main thread: 1
child thread: 2
pthread_once
pthread_once
はマルチスレッド環境で1回のみ実行され、マルチスレッド環境で1回のみ実行する必要がある操作をpthread_once
に渡すと、スレッドは安全に1回のみ実行されます.pthread_once
には2つのパラメータがあります.pthread_once_t
変数であり、識別子に相当するtype:pthread_once_t
void(*func)(void)
once_run
は1回のみ実行されるが、実行されるたびに結果が異なる場合があり、once_run
はスレッド1で実行される場合もあり、スレッド2で実行される場合もある.
#include
#include
#include
using namespace std;
pthread_once_t once = PTHREAD_ONCE_INIT;
void once_run(void)
{
cout<
出力:
thread 2 enter
once_run in thread 2
thread 2 return
thread 3 enter
thread 3 return
pthread_cancel
cancel
信号を指定したスレッドに送信します.パラメータスレッド識別子は1つしかありません.タイプはpthread_t
です.使い方は簡単です.ここではあまり紹介しません.原理を理解する学生はlinuxの下でmanコマンドでもっと知ることができます.man pthread_cancel
pthread_kill
あるスレッドに信号を渡すには、作成したスレッドで
signal(SIGKILL,sig_handler)
関数を使用して信号を処理する必要があります.スレッドにSIGQUIT
を送信したが、スレッドがsignal処理関数を実装していない場合、プロセス全体が終了します.pthread_kill
の2つのパラメータ:pthread_t
int