ホームページ 運用・保守 Linuxの運用と保守 Linux マルチスレッド プログラミングのサンプル コード分析

Linux マルチスレッド プログラミングのサンプル コード分析

May 26, 2023 pm 10:04 PM
linux

まず例を挙げてみましょう。数値をインクリメントするために 2 つのスレッドを作成します。おそらくこの例には実用的な価値はありませんが、少し変更するだけで他の場所でも使用できます。

コード:

/*thread_example.c : c multiple thread programming in linux
 *author : falcon
 *e-mail : tunzhj03@st.lzu.edu.cn
 */
#include <pthread.h>
#include <stdio.h>
#include <sys/time.h>
#include <string.h>
#define max 10

pthread_t thread[2];
pthread_mutex_t mut;
int number=0, i;

void *thread1()
{
    printf ("thread1 : i&#39;m thread 1/n");

    for (i = 0; i < max; i++)
    {
        printf("thread1 : number = %d/n",number);
        pthread_mutex_lock(&mut);
            number++;
        pthread_mutex_unlock(&mut);
        sleep(2);
    }


    printf("thread1 :主函数在等我完成任务吗?/n");
    pthread_exit(null);
}

void *thread2()
{
    printf("thread2 : i&#39;m thread 2/n");

    for (i = 0; i < max; i++)
    {
        printf("thread2 : number = %d/n",number);
        pthread_mutex_lock(&mut);
            number++;
        pthread_mutex_unlock(&mut);
        sleep(3);
    }


    printf("thread2 :主函数在等我完成任务吗?/n");
    pthread_exit(null);
}

void thread_create(void)
{
    int temp;
    memset(&thread, 0, sizeof(thread));     //comment1
    /*创建线程*/
    if((temp = pthread_create(&thread[0], null, thread1, null)) != 0) //comment2   
        printf("线程1创建失败!/n");
    else
        printf("线程1被创建/n");

    if((temp = pthread_create(&thread[1], null, thread2, null)) != 0) //comment3
        printf("线程2创建失败");
    else
        printf("线程2被创建/n");
}

void thread_wait(void)
{
    /*等待线程结束*/
    if(thread[0] !=0)      {       //comment4          pthread_join(thread[0],null);
        printf("线程1已经结束/n");
     }
    if(thread[1] !=0)      {         //comment5        pthread_join(thread[1],null);
        printf("线程2已经结束/n");
     }
}

int main()
{
    /*用默认属性初始化互斥锁*/
    pthread_mutex_init(&mut,null);

    printf("我是主函数哦,我正在创建线程,呵呵/n");
    thread_create();
    printf("我是主函数哦,我正在等待线程完成任务阿,呵呵/n");
    thread_wait();

    return 0;
}
ログイン後にコピー

最初にコンパイルして実行しましょう

引用:

falcon@falcon:~/program/c/code/ftp$ gcc -lpthread -o thread_example thread_example.c
falcon@falcon:~/program/c/code/ftp$ ./thread_example
我是主函数哦,我正在创建线程,呵呵
线程1被创建
线程2被创建
我是主函数哦,我正在等待线程完成任务阿,呵呵
thread1 : i&#39;m thread 1
thread1 : number = 0
thread2 : i&#39;m thread 2
thread2 : number = 1
thread1 : number = 2
thread2 : number = 3
thread1 : number = 4
thread2 : number = 5
thread1 : number = 6
thread1 : number = 7
thread2 : number = 8
thread1 : number = 9
thread2 : number = 10
thread1 :主函数在等我完成任务吗?
线程1已经结束
thread2 :主函数在等我完成任务吗?
线程2已经结束
ログイン後にコピー

サンプル コードのコメントはより明確になるはずです。以下に引用します。上記のいくつかの関数と変数はインターネット上にあります。

引用:

スレッド関連の操作

一pthread_t

pthread_t はヘッダー ファイル /usr/include/bits/pthreadtypes.h で定義されています。
Typedef unsigned long int pthread_t;
スレッドの識別子です。

二pthread_create

関数 pthread_create はスレッドの作成に使用されます。そのプロトタイプは次のとおりです:
extern int pthread_create __p ((pthread_t *__thread, __const pthread_attr_t *__attr,
void * (*__start_routine) (void *), void *__arg));
最初のパラメータはスレッド識別子へのポインタ、2 番目のパラメータはスレッド属性の設定に使用され、3 番目のパラメータはスレッドの開始位置です。スレッド実行関数。開始アドレス、最後のパラメータは関数を実行するためのパラメータです。ここで、関数スレッドはパラメーターを必要としないため、最後のパラメーターは null ポインターに設定されます。また、2 番目のパラメーターを null ポインターに設定します。これにより、デフォルトの属性を持つスレッドが生成されます。スレッド属性の設定と変更については次のセクションで説明します。スレッドが正常に作成された場合、関数は 0 を返します。0 でない場合、スレッドの作成は失敗します。一般的なエラーの戻りコードは eagain と einval です。前者は、スレッドの数が多すぎるなど、システムが新しいスレッドの作成を制限していることを意味し、後者は、2 番目のパラメータで表されるスレッド属性値が不正であることを意味します。スレッドが正常に作成されると、新しく作成されたスレッドはパラメーター 3 とパラメーター 4 で決定された関数を実行し、元のスレッドはコードの次の行の実行を続けます。

3 つの pthread_join pthread_exit

関数 pthread_join は、スレッドの終了を待つために使用されます。関数のプロトタイプは次のとおりです:
extern int pthread_join __p ((pthread_t __th, void **__thread_return));
最初のパラメータは待機するスレッド識別子で、2 番目のパラメータはユーザー定義のポインタです。待機中のスレッドの戻り値を格納するために使用できます。この関数はスレッドブロック関数です。この関数を呼び出した関数は、待機中のスレッドが終了するまで待機します。関数が復帰すると、待機中のスレッドのリソースが回復されます。スレッドを終了するには 2 つの方法があります。1 つは上の例と同様です。関数が終了すると、その関数を呼び出したスレッドも終了します。もう 1 つは、関数 pthread_exit を使用する方法です。その関数プロトタイプは次のとおりです。
extern void pthread_exit __p ((void *__retval)) __attribute__ ((__noreturn__));
pthread_join の 2 番目のパラメーター thread_return が次のとおりである限り、唯一のパラメーターは関数の戻りコードです。 null ではない場合、この値は thread_return に渡されます。最後に注意すべきことは、1 つのスレッドを複数のスレッドで待機させることはできないということです。そうでない場合は、シグナルを受信した最初のスレッドが正常に戻り、pthread_join を呼び出す残りのスレッドはエラー コード esrch を返します。
このセクションでは、最も単純なスレッドを作成し、最もよく使用される 3 つの関数 pthread_create、pthread_join、および pthread_exit を習得しました。次に、スレッドのいくつかの一般的なプロパティとその設定方法を見てみましょう。

ミューテックス ロック関連

ミューテックス ロックは、一定期間内に 1 つのスレッドだけがコードを実行することを保証するために使用されます。

1pthread_mutex_init

関数 pthread_mutex_init は、ミューテックス ロックを生成するために使用されます。 null パラメータは、デフォルトのプロパティが使用されることを示します。特定の属性のミューテックスを宣言する必要がある場合は、関数 pthread_mutexattr_init を呼び出す必要があります。関数 pthread_mutexattr_setpshared および関数 pthread_mutexattr_settype は、ミューテックス ロック属性を設定するために使用されます。前の関数は、pthread_process_private と pthread_process_shared という 2 つの値を持つ属性 pshared を設定します。前者は異なるプロセスのスレッドを同期するために使用され、後者はこのプロセスの異なるスレッドを同期するために使用されます。上の例では、デフォルトの属性 pthread_process_private を使用しています。後者はミューテックス ロック タイプの設定に使用され、オプションのタイプは pthread_mutex_normal、pthread_mutex_errorcheck、pthread_mutex_recursive、および pthread _mutex_default です。これらはそれぞれ異なるリストおよびロック解除メカニズムを定義しており、通常の状況では、最後のデフォルト属性が選択されます。

2 pthread_mutex_lock pthread_mutex_unlock pthread_lay_np

pthread_mutex_lock ステートメントは、ミューテックス ロックでロックを開始します。後続のコードは、pthread_mutex_unlock が呼び出されるまでロックされます。つまり、このコードは 1 つのスレッドによってのみ呼び出され、実行されます。同時に。スレッドが pthread_mutex_lock を実行するときに、その時点でロックが別のスレッドによって使用されている場合、スレッドはブロックされます。つまり、プログラムは別のスレッドがミューテックス ロックを解放するまで待機します。 ######知らせ:###

1 上記の 2 つのスリープはデモのためだけではなく、スレッドを一定期間スリープさせて、スレッドがミューテックス ロックを解放し、別のスレッドがこのロックを使用するのを待機できるようにするためのものであることに注意してください。 。この問題については、以下の参考文献 1 で説明されています。ただし、Linux には pthread_lay_np 関数がないようなので(試してみたところ、定義された関数への参照がありませんと表示されました)、代わりに sleep を使用しましたが、参考 2 には別の方法が記載されているようです。これは、それを実現する方法を提供する pthread_cond_timedwait. に置き換えられます。

2 中のコメント 1 ~ 5 に注目してください。問題を見つけるのに数時間かかった箇所です。
comment1、comment4、comment5 がない場合、pthread_join 時にセグメンテーション違反が発生します また、上記の comment2 と comment3 が根本原因となるため、コード全体を忘れずに記述してください。上記スレッドが正常に作成されていない可能性があるため、そのスレッドの終了を待つことができず、pthread_joinを使用するとセグメンテーションフォルト(不明なメモリ領域にアクセスされる)が発生します。さらに、memset を使用する場合は、string.h ヘッダー ファイルをインクルードする必要があります

以上がLinux マルチスレッド プログラミングのサンプル コード分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

マルチスレッドをC言語で実装する4つの方法 マルチスレッドをC言語で実装する4つの方法 Apr 03, 2025 pm 03:00 PM

言語のマルチスレッドは、プログラムの効率を大幅に改善できます。 C言語でマルチスレッドを実装する4つの主な方法があります。独立したプロセスを作成します。独立して実行される複数のプロセスを作成します。各プロセスには独自のメモリスペースがあります。擬似マルチスレッド:同じメモリ空間を共有して交互に実行するプロセスで複数の実行ストリームを作成します。マルチスレッドライブラリ:pthreadsなどのマルチスレッドライブラリを使用して、スレッドを作成および管理し、リッチスレッド操作機能を提供します。 Coroutine:タスクを小さなサブタスクに分割し、順番に実行する軽量のマルチスレッド実装。

web.xmlを開く方法 web.xmlを開く方法 Apr 03, 2025 am 06:51 AM

web.xmlファイルを開くには、次の方法を使用できます。テキストエディター(メモ帳やテキストエディットなど)を使用して、統合開発環境(EclipseやNetBeansなど)を使用してコマンドを編集できます(Windows:Notepad web.xml; Mac/Linux:Open -A Textedit Web.xml)

PythonインタープリターはLinuxシステムで削除できますか? PythonインタープリターはLinuxシステムで削除できますか? Apr 02, 2025 am 07:00 AM

Linux Systemsに付属するPythonインタープリターを削除する問題に関して、多くのLinuxディストリビューションは、インストール時にPythonインタープリターをプリインストールし、パッケージマネージャーを使用しません...

Linuxは何に最適なものですか? Linuxは何に最適なものですか? Apr 03, 2025 am 12:11 AM

Linuxは、サーバー管理、組み込みシステム、デスクトップ環境として最適です。 1)サーバー管理では、LinuxはWebサイト、データベース、アプリケーションをホストするために使用され、安定性と信頼性を提供します。 2)組み込みシステムでは、Linuxは柔軟性と安定性のため、スマートホームおよび自動車電子システムで広く使用されています。 3)デスクトップ環境では、Linuxは豊富なアプリケーションと効率的なパフォーマンスを提供します。

Debian Hadoopの互換性はどうですか Debian Hadoopの互換性はどうですか Apr 02, 2025 am 08:42 AM

DebianLinuxは、その安定性とセキュリティで知られており、サーバー、開発、デスクトップ環境で広く使用されています。現在、DebianとHadoopとの直接的な互換性に関する公式の指示が不足していますが、この記事では、DebianシステムにHadoopを展開する方法について説明します。 Debianシステムの要件:Hadoop構成を開始する前に、DebianシステムがHadoopの最小動作要件を満たしていることを確認してください。これには、必要なJavaランタイム環境(JRE)とHadoopパッケージのインストールが含まれます。 Hadoop展開手順:Hadoopをダウンロードして解凍:公式ApachehadoopのWebサイトから必要なHadoopバージョンをダウンロードして解決します

GOを使用してOracleデータベースに接続するときにOracleクライアントをインストールする必要がありますか? GOを使用してOracleデータベースに接続するときにOracleクライアントをインストールする必要がありますか? Apr 02, 2025 pm 03:48 PM

GOを使用してOracleデータベースに接続するときにOracleクライアントをインストールする必要がありますか? GOで開発するとき、Oracleデータベースに接続することは一般的な要件です...

Debian文字列は、複数のブラウザと互換性があります Debian文字列は、複数のブラウザと互換性があります Apr 02, 2025 am 08:30 AM

「DebianStrings」は標準的な用語ではなく、その特定の意味はまだ不明です。この記事は、ブラウザの互換性について直接コメントすることはできません。ただし、「DebianStrings」がDebianシステムで実行されているWebアプリケーションを指す場合、そのブラウザの互換性はアプリケーション自体の技術アーキテクチャに依存します。ほとんどの最新のWebアプリケーションは、クロスブラウザーの互換性に取り組んでいます。これは、次のWeb標準と、適切に互換性のあるフロントエンドテクノロジー(HTML、CSS、JavaScriptなど)およびバックエンドテクノロジー(PHP、Python、Node.jsなど)を使用することに依存しています。アプリケーションが複数のブラウザと互換性があることを確認するには、開発者がクロスブラウザーテストを実施し、応答性を使用する必要があることがよくあります

See all articles