[オペレーティングシステム] Linux上でマルチスレッド・プログラムを作成およびデバッグ

この記事のための環境:
LinuxのCentOSの-7.shared 3.10.0-693.5.2.el7.x86_64#1 SMP金10月20日20時32分50秒UTC 2017 x86_64のx86_64のx86_64版のGNU / Linux
gccのバージョン4.8.5 20150623(Red Hatの4.8 0.5から39)(GCC)

ここで使用されるように、POSIXスレッドライブラリは、ヘッダファイルを導入する必要がpthread.h追加するには、注意を払うには、コンパイル時に-lpthreadパラメータを。

POSIXは、インタフェースが提供すべきであるオペレーティングシステム合意標準である、pスレッドは、POSIXスレッドです。C ++ 11やPython、Javaスレッドライブラリが構築されています。

スレッドの作成

int pthread_create(
	pthread_t *thread, 
	const pthread_attr_t *attr,
	void *(*start_routine) (void *), 
	void *arg
);

パラメータ:
スレッドがスレッドIDを返す出力パラメータです。
あなたは、スレッドがATTR、NULLがデフォルト塗りつぶし属性を示す属性を設定することができます。
start_routineが、関数が実行の入り口スレッドで、関数ポインタです。
引数のパラメータは、start_routineはの関数です。
それはあなたが複数の機能を渡す必要がある場合は、構造体または他の方法を使用する必要があり、この機能は、複数のパラメータを渡す引数(可変パラメータ)がサポートされていないことは注目に値します。

戻り値:
成功した場合にエラーコードを返すために失敗を0を返します。

栗:
この新しいスレッド内では、このパラメータをパラメータとプリントを渡し、スレッドを作成します。
ここに画像を挿入説明

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

struct ThreadArg {
    int num;
};

void* ThreadEntry(void* arg) {
    while (1) {
        printf("In ThreadEntry, %lu, arg %d\n", pthread_self(), ((struct ThreadArg*) arg)->num);
        sleep(1);
    }
}

int main() {
    pthread_t tid;
    struct ThreadArg ta;
    ta.num = 20;
    pthread_create(&tid, NULL, ThreadEntry, &ta);
    while (1) {
        printf("In Main Thread, %lu\n", pthread_self());
        sleep(1);
    }

    return 0;
}

注意:
上記のコードは、使用pthread_self()オペレーティングシステムは、スレッドIDを取得するためにシステムコールを提供し、ライブラリによって提供されるPOSIXスレッドライブラリ関数であるスレッドを取得するためにIDをgettid()

pthread_t pthread_self(void);
pid_t gettid(void);

あなたは同じスレッドにいるときしかし、2つの関数は値を返さ発見と同じではありません呼び出します。

コールASで、このことにより、返されたスレッドIDが同じでAものではありません、POSIXスレッドID。
(IE、不透明な値でpthread_selfによって返された(3))。
シングルスレッドのプロセスのために、カーネルTID == PID、マルチスレッドプロセスのために、彼らは同じPID、異なるTIDを持っています。TIDカーネル本当のPIDとTID情報を記述するために使用されます。
pthread_selfの戻りは、POSIXスレッドIDを定義している男のマニュアルは明記し、カーネルスレッドTID異なります。これは、スレッドが終了するが、新たに作成されたスレッドは、元のIDを再利用することができたときに、異なるスレッドを区別するために使用されるだけのプロセスです。

差分gettid()とpthread_self()の

スレッドの終了

:進行せず、スレッドの終了を終了したい
スレッドハンドラから、1 return
2、スレッドは自分自身を呼び出すpthread_exit儀式自殺。

void pthread_exit(void *retval);

パラメータ:パラメータ入力&出力タイプ。
ご注意ください:Pthread_exitメモリセルパラメータ点は、グローバルまたは他のスレッドが取得するときに機能が引き出されたスレッドへのポインタを返すためのmallocは、スレッド関数のスタック上に割り当てられていないことにより、割り当てられなければなりません。

3人の兄弟のスレッドを呼び出しpthread_cancel、同じプロセス内の他のスレッドを終了します。

int pthread_cancel(pthread_t thread);

パラメータ:スレッドID
戻り値:成功時に0を返し、エラーコードを返すために失敗。
ご注意ください:これは、pthread_cancelあなたがサモナーキャニオンキルINGは、夕食にあなたを呼び出すあなたのお母さんのスレッドを終了させるために適度ではなく、抽象的なアン例殺すを強制されている、あなたは最後の食事の前に少し待たなければならないことがあります。

スレッドの待機

なぜスレッドを待ちますか?
例えば、大規模な行列乗算演算は、複数のスレッド、計算の各ねじ部、ここでpthread_joinをロジックを確実にするために使用されるメインスレッドの要約結果を実行するすべてのスレッドのための最終的なウェイトを用いて計算することができます。

int pthread_join(pthread_t thread, void **retval);

パラメータ:スレッドIDをスレッド、スレッドの戻り値へのポイントは、スレッドは戻り値を気にしないことをポインタにRETVALポイントはNULLを埋めることができます。
戻り値:成功した場合にエラーコードを返すために失敗を0を返します。
この関数はスレッドIDスレッドとして終了されるまで、スレッドのハングを待つと呼ばれています。:異なる方法でスレッドスレッド終端は、最終的な状態が異なるpthread_joinをすることにより得られる
戻り値に戻すスレッド、手段VALUE_ PTRの点を通るねじバックがスレッド関数のスレッド内に格納されている場合、1。
図2は、場合呼び出したスレッドは、スレッドの他のスレッドの例外のpthread_cancel最終オフユニットVALUE_ PTRポイントが一定PTHREAD_CANCELEDに格納されます。
図3に示すように、スレッドは、自身がpthread_exitスレッドコールが終了し、value_ptr尖った部はpthread_exitに渡されるパラメータに格納されている場合。

スレッドの分離

同様に、スレッドの代わりに生と死の問題を分離した後、SIGCHLDシグナルを無視し、またないpthread_join回復。

int pthread_detach(pthread_t thread);

自分自身を分離所有することができ、それはまた、兄弟のスレッドを分離することができます。
pthread_detach(pthread_self());

GDBデバッグマルチスレッド・プログラムを使用して

0、マルチスレッド・プログラムのデバッグにgdbを使って

コンパイル時に追加するには、プログラムのニーズをデバッグするために使用GDB -gオプション、なぜ?行くためにBaiduの。

gdb attach 28966
info thread # 查看所有线程信息
bt # 查看当前线程调用栈
thread 2 # 切换当前线程

ここに画像を挿入説明

1、番組情報の全てのスレッドを見ます

ps -eLf | grep a.out

パラメータ:-Lは、psここLWP、スレッドIDを表し、gettid GETは同じです。
ここに画像を挿入説明

2は、ライブラリを依存している番組を視聴します

ldd a.out

ここに画像を挿入説明
3、プロセスが複数のスレッドとスレッドのコールスタックを持って見ます

pstack 27779

ここに画像を挿入説明


EOF

公開された73元の記事 ウォン称賛90 ビュー40000 +

おすすめ

転載: blog.csdn.net/Hanoi_ahoj/article/details/105191592