Linux C——マルチスレッドの基本概念とAPI関数


一、スレッドとプロセスの関係、プロセスと比較してスレッドにはどのような利点がありますか?
1.スレッドとプロセスの関係
①スレッドはプロセスの実行フローであり、CPUのスケジューリングと割り当ての基本単位であり、プロセスよりも小さく独立して実行できる基本単位である.
②1つのプロセスは、複数のスレッド(比較的独立した実行フローを多く持つユーザプログラムがアプリケーションの大部分のデータ構造を共有する)からなり、スレッドは同じプロセスに属する他のスレッドとプロセスが所有するすべてのリソースを共有する.
③「プロセス——リソース割当の最小単位、スレッド——プログラム実行の最小単位」
4プロセスには独立したアドレス空間があり、1つのプロセスがクラッシュした後、保護モードでは他のプロセスに影響を与えないが、スレッドは1つのプロセスの異なる実行パスにすぎない.
⑤スレッドには独自のスタックとローカル変数があるが、スレッドには単独のアドレス空間がなく、1つのスレッドが死ぬのはプロセス全体が死ぬのと同じであるため、マルチプロセスのプログラムはマルチスレッドのプログラムより丈夫であるが、プロセス切替時には資源がかかり、効率が悪い.しかし、いくつかの変数を同時に実行し、共有する必要がある同時操作は、スレッドのみで、プロセスは使用できません.
 
2.プロセスと比較したメリット
①プロセスと比較する、非常に「倹約」なマルチタスク操作方式である.Linuxシステムの下で、新しいプロセスを起動するには、独立したアドレス空間に割り当てる必要があります.多くのデータテーブルを構築して、コードセグメント、スタックセグメント、データセグメントを維持します.これは「高価」なマルチタスク作業方法です.
②スレッド間の便利な通信メカニズム.
異なるプロセスにとって、それらは独立したデータ空間を持っており、データの伝達を行うにはプロセス間通信の方式しかできない.この方式は時間がかかるだけでなく、不便である.
スレッドはそうではありません.同じプロセスのスレッド間でデータ空間が共有されているため、1つのスレッドのデータは他のスレッドに直接使用できます.これは迅速であるだけでなく、便利です.
③マルチCPUシステムをより効率的にする.オペレーティングシステムは、スレッド数がCPU数以下の場合、異なるスレッドが異なるCPU上で動作ことを保証する.
④プログラム構造を改善する.1つの長くて複雑なプロセスは、複数のスレッドに分けて、いくつかの独立したまたは半独立した実行部分になることを考慮することができ、このようなプログラムは理解と修正に有利である.
 
二、スレッドの作成、待機、終了のAPI関数の詳細
1.スレッドの作成pthread_create
関数プロトタイプ:int pthread_create(pthread_t *tidp,const pthread_attr_t *attr,(void*)(*start_rtn)(void*),void *arg);
パラメータ:tidp:スレッド識別子を指すポインタです.
attr:スレッドプロパティを設定します.
      start_routine:スレッドの実行関数.
arg:スレッド実行関数に入力するパラメータ.
戻り値:成功0、エラー戻りエラーコード
#include 
#include 
 
void *myThread1(void)
{
    int i;
    for (i=0; i<3; i++)
    {
        printf("This is the 1st pthread,created by zieckey.
"); sleep(1);//Let this thread to sleep 1 second,and then continue to run } } void *myThread2(void) { int i; for (i=0; i<3; i++) { printf("This is the 2st pthread,created by zieckey.
"); sleep(1); } } int main() { int i=0, ret=0; pthread_t id1,id2; /* 1*/ ret = pthread_create(&id1, NULL, (void*)myThread1, NULL); if (ret) { printf("Create pthread error!
"); return 1; } /* 2*/ ret = pthread_create(&id2, NULL, (void*)myThread2, NULL); if (ret) { printf("Create pthread error!
"); return 1; } pthread_join(id1, NULL); pthread_join(id2, NULL); return 0; }

2.スレッド終了待ちpthread_join
関数プロトタイプ:int pthread_join(pthread_t thread, void **retval);
パラメータ:hread:スレッド識別子、すなわちスレッドIDは、一意のスレッドを識別します.
retval:待機スレッドの戻り値を格納するためにユーザ定義のポインタ.
戻り値:0は成功を表します.失敗しました.エラー番号を返します.
#include 
#include 
#include 
 
void *thread(void *str)
{
    int i;
    for (i = 0; i < 10; ++i)
    {
        sleep(2);
        printf( "This in the thread : %d
" , i ); } return NULL; } int main() { pthread_t pth; int i; int ret = pthread_create(&pth, NULL, thread, (void *)(i)); pthread_join(pth, NULL); printf("123
"); for (i = 0; i < 10; ++i) { sleep(1); printf( "This in the main : %d
" , i ); } return 0; }

3.スレッド終了pthread_exit
関数プロトタイプ:void pthread_exit(void* retval)
戻り値:スレッドの戻り値を呼び出し、pthread_などの他の関数を使用できます.joinが取得する
 
スレッドの戻り値の表示
#include 
#include 
#include 
 
void *create(void *arg)
{
    printf("new thread is created ... 
"); return (void *)8; } int main(int argc,char *argv[]) { pthread_t tid; int error; void *temp; error = pthread_create(&tid, NULL, create, NULL); printf("main thread!
"); if( error ) { printf("thread is not created ...
"); return -1; } error = pthread_join(tid, &temp); if( error ) { printf("thread is not exit ...
"); return -2; } printf("thread is exit code %d
", (int)temp); return 0; }

三、スレッドの作成時にパラメータはどのように伝達されますか?
#include 
#include 
#include 
#include 
 
struct menber
{
    int a;
    char *s;
};
 
void *create(void *arg)
{
    struct menber *temp;
    temp=(struct menber *)arg;
    printf("menber->a = %d  
",temp->a); printf("menber->s = %s
",temp->s); return (void *)0; } int main(int argc,char *argv[]) { pthread_t tidp; int error; struct menber *b; b=(struct menber *)malloc( sizeof(struct menber) ); b->a = 4; b->s = "zieckey"; error = pthread_create(&tidp, NULL, create, (void *)b); if( error ) { printf("phread is not created...
"); return -1; } sleep(1); printf("pthread is created...
"); return 0; }