C LANGUAGE TECHNOLOGY

【C言語】スレッドの生成と実行【pthread,マルチスレッド,スレッドIDの取得】

2021年9月22日

悩んでいる人
悩んでいる人

C言語でスレッドを教えて!

こういった悩みにお答えします.

本記事の信頼性

  • リアルタイムシステムの研究歴12年.
  • 東大教員の時に,英語でOS(Linuxカーネル)の授業.
  • 2012年9月~2013年8月にアメリカのノースカロライナ大学チャペルヒル校(UNC)コンピュータサイエンス学部で客員研究員として勤務.C言語でリアルタイムLinuxの研究開発.
  • プログラミング歴15年以上,習得している言語: C/C++PythonSolidity/Vyper,Java,Ruby,Go,Rust,D,HTML/CSS/JS/PHP,MATLAB,Verse(UEFN), Assembler (x64,ARM).
  • 東大教員の時に,C++言語で開発した「LLVMコンパイラの拡張」,C言語で開発した独自のリアルタイムOS「Mcube Kernel」GitHubにオープンソースとして公開
  • 2020年1月~現在はアメリカのノースカロライナ州チャペルヒルにあるGuarantee Happiness LLCのCTOとしてECサイト開発やWeb/SNSマーケティングの業務.2022年6月~現在はアメリカのノースカロライナ州チャペルヒルにあるJapanese Tar Heel, Inc.のCEO兼CTO.
  • 最近は自然言語処理AIイーサリアムに関する有益な情報発信に従事.
    • (AI全般を含む)自然言語処理AIの論文の日本語訳や,AIチャットボット(ChatGPT,Auto-GPT,Gemini(旧Bard)など)の記事を50本以上執筆.アメリカのサンフランシスコ(広義のシリコンバレー)の会社でプロンプトエンジニア・マネージャー・Quality Assurance(QA)の業務委託の経験あり.
    • (スマートコントラクトのプログラミングを含む)イーサリアムや仮想通貨全般の記事を200本以上執筆.イギリスのロンドンの会社で仮想通貨の英語の記事を日本語に翻訳する業務委託の経験あり.

こういった私から学べます.

C言語を独学で習得することは難しいです.

私にC言語の無料相談をしたいあなたは,公式LINE「ChishiroのC言語」の友だち追加をお願い致します.

私のキャパシティもあり,一定数に達したら終了しますので,今すぐ追加しましょう!

友だち追加

独学が難しいあなたは,元東大教員がおすすめするC言語を学べるオンラインプログラミングスクール5社で自分に合うスクールを見つけましょう.後悔はさせません!

スレッド

スレッドとは,OSにおけるプログラムの実行単位です.

スレッドが管理する情報はプロセスより少ないので,スレッド間のコンテキストスイッチのオーバヘッドも小さいです.

プロセスと比較して,あるスレッドは同じプロセス内の他のスレッド同士でメモリ空間を共有するため,スレッド間のデータのやり取りのオーバヘッドが小さくできます.

同じプロセス内のスレッド同士でメモリ空間を共有するため,あるスレッドは同じプロセス内の他のスレッドのデータを変更すると,正常に動作しなくなることがあります.

なので,マルチスレッドプログラミングでは,スレッド間で共有するデータの読み書きに注意する必要があります.

プロセスの生成と実行を知りたいあなたはこちらからどうぞ.

本記事では,x86-64だけでなくARM64(AARCH64)用のコードがあります.

ARM64用の開発環境の構築は以下の記事を参考にして下さい.

pthreadによるマルチスレッドプログラミング

pthreadによるマルチスレッドプログラミングを紹介します.

pthread_create関数は,呼び出し元のスレッドと並行して実行する新しいスレッドを生成する関数です.

新しいスレッドは,argを第1引数とするstart_routineという関数になります.

引数attrには,その新しいスレッドに適用するスレッド属性を指定します.

スレッド属性に関する詳細は,PTHREAD_ATTR_INITに記載されています.

成功すると新しく作成したスレッドの識別子が引数threadの指す領域へ格納され,関数の返り値は0になります.

pthread_join関数は,呼び出し元のスレッドの実行を停止し,thで指定したスレッドが終了するのを待ちます.

thread_returnがNULLでない場合,thの返り値がthread_returnで指し示される領域に格納されます.

pthreadでスレッドを生成して実行するコードは以下になります.

実行結果は以下になります.

pthreadのライブラリを利用する時は,-lpthreadオプションを付けてコンパイルすることに注意して下さい.

pthreadでスレッドIDの取得

pthreadでスレッドIDを取得する方法を紹介します.

pthread_self関数

pthread_self関数は,呼び出し元のスレッドのIDを取得する関数です.

ここで,pthread_self関数で取得するスレッドIDはLinuxが管理するスレッドIDではないことに注意して下さい.

ではpthread_self関数の返り値が何かというと,生成したpthreadが利用するスタックのアドレスになります.

このスタックのアドレスの値は,スレッドが利用可能なメモリ領域の最大値もしくは近い値だと思われます.

Linuxが管理するスレッドIDとは,psコマンドを-Lオプション付きで実行した時に表示される軽量プロセス(LWP:Light-Weight Process)のIDのことです.

以下のpsコマンドの実行結果で,PIDがプロセスID,LWPがLinuxが管理するスレッドIDになります.

pthread_self関数を利用し,x86-64/ARM64の命令でスタックアドレスを取得して表示するコードは以下になります.

17行目でx86-64のmov命令,19行目でARM64のmov命令を利用していることに注意して下さい.

x86-64の実行結果は以下になります.

tid毎のpthread_create関数の第1引数とpthread_self関数の返り値が同じアドレスになっています.

また,func_thread関数でスタックポインタを取得した値saは,上記のアドレスから0x840引いた値になっていることがわかります.

ARM64の実行結果は以下になります.

x86-64と同様に,tid毎のpthread_create関数の第1引数とpthread_self関数の返り値が同じアドレスになっています.

また,x86-64とは異なり,saは上記のアドレスから0x850引いた値になっていることがわかります.

Linux固有のgettid関数

Linux固有のgettid関数は,Linuxが管理するスレッドIDを取得する関数です.

こちらのスレッドIDはpsコマンドで-Lオプションを付けて実行すると表示されるLWPの値と同じになります.

gettid関数を利用するコードは以下になります.

実行結果は以下になります.

2行目の実行方法「a.out&; ps -L; fg」は少し複雑ですが,セミコロン「;」で区切って以下のようになります.

  • a.out&:実行ファイルをバックグラウンドのジョブとして実行
  • ps -L:psコマンドでPIDとLWPを表示
  • fg:バックグラウンドで実行しているものをフォアグラウンドのジョブとして実行(または再開)

4行目のgettid関数の返り値と8行目のLWP,5行目のgettid関数の返り値と9行目のLWPがそれぞれ同じ値であることがわかります.

参考:pthread_create関数の第1引数を利用して生成したスレッドのスレッドIDの取得

pthread_create関数の第1引数pthreadを利用して生成したスレッドのスレッドIDを取得する方法を紹介します.

生成したスレッドのスレッドIDは,x86-64の場合はpthread + 0x2d0,ARM64の場合はpthread + 0xd0が指すアドレスにあります.

この実装は実験的ですので,LinuxカーネルのバージョンやGCCコンパイラのオプションによっては動作しない可能性があることに注意して下さい.

生成したスレッドのスレッドIDを取得するgettid_pthread関数を自作したコードは以下になります.

x64の実行結果は以下になります.

生成元のスレッドが呼び出しているgettid_pthread関数の返り値と,生成したスレッドが呼び出しているfunc_thread関数内のgettid関数の返り値が,同じスレッドID(11359)になっていることがわかります.

ARM64の実行結果は以下になります.同様です.

まとめ

C言語でスレッドの生成と実行方法を紹介しました.

具体的には,pthreadによるマルチスレッドプログラミングとスレッドIDの取得方法を解説しました.

C11規格でマルチスレッドプログラミングを知りたいあなたはこちらからどうぞ.

C言語を独学で習得することは難しいです.

私にC言語の無料相談をしたいあなたは,公式LINE「ChishiroのC言語」の友だち追加をお願い致します.

私のキャパシティもあり,一定数に達したら終了しますので,今すぐ追加しましょう!

友だち追加

独学が難しいあなたは,元東大教員がおすすめするC言語を学べるオンラインプログラミングスクール5社で自分に合うスクールを見つけましょう.後悔はさせません!

-C LANGUAGE, TECHNOLOGY
-, , , , , , , , ,