SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

連載記事

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

CodeZine BOOKS(コードジン・ブックス)は、CodeZineの連載からカットアップした、開発現場の課題解決に役立つ書籍シリーズです。

書籍に関する記事を見る

'); googletag.cmd.push(function() { googletag.pubads().addEventListener('slotRenderEnded', function(e) { var ad_id = e.slot.getSlotElementId(); if (ad_id == 'div-gpt-ad-1659428980688-0') { var ad = $('#'+ad_id).find('iframe'); if ($(ad).width() == 728) { var ww = $(window).width(); ww = ww*0.90; var style = document.createElement("style"); document.head.appendChild( style ); var sheet = style.sheet; sheet.insertRule( "#div-gpt-ad-1659428980688-0 iframe {-moz-transform: scale("+ww/728+","+ww/728+");-moz-transform-origin: 0 0;-webkit-transform: scale("+ww/728+","+ww/728+");-webkit-transform-origin: 0 0;-o-transform: scale("+ww/728+","+ww/728+");-o-transform-origin: 0 0;-ms-transform: scale("+ww/728+","+ww/728+");-ms-transform-origin: 0 0;}", 0 ); sheet.insertRule( "#div-gpt-ad-1659428980688-0 div{ height:"+(90*ww/728)+"px;width:"+728+"px;}", 0 ); } else { if ($(window).width() < 340) { var ww = $(window).width(); ww = ww*0.875; var style = document.createElement("style"); document.head.appendChild( style ); var sheet = style.sheet; sheet.insertRule( "#div-gpt-ad-1659428980688-0 iframe {-moz-transform: scale("+ww/320+","+ww/320+");-moz-transform-origin: 0 0;-webkit-transform: scale("+ww/320+","+ww/320+");-webkit-transform-origin: 0 0;-o-transform: scale("+ww/320+","+ww/320+");-o-transform-origin: 0 0;-ms-transform: scale("+ww/320+","+ww/320+");-ms-transform-origin: 0 0;}", 0 ); sheet.insertRule( "#div-gpt-ad-1659428980688-0 div{ height:"+(180*ww/320)+"px;width:"+320+"px;}", 0 ); } } } }); }); } else { document.write('
'); document.write('
'); }
インテルTBBを通じて学ぶ並列処理

マルチスレッドを安全に実行する

スレッドセーフの勘所

  • X ポスト
  • このエントリーをはてなブックマークに追加

 この記事では、マルチスレッドについて、過去に掲載された誤解を招く表現を多く含む記事を訂正し、マルチスレッドプログラミングを安全に設計する方法を説明します。

  • X ポスト
  • このエントリーをはてなブックマークに追加

はじめに

 この記事は、インドリ氏による『スレッドセーフとインテルTBBのコンテナ』に記載されている誤りを訂正することを目的としています。インドリ氏の記事では、TBBコンテナの紹介に注意するあまり、マルチスレッドプログラミングに潜む危険、その危険を取り除く方法についての記述が正しくありません。本記事では、マルチスレッドプログラミングを安全に設計する方法を説明することを目的とします。

 本記事で用いるコードは、C言語に類似していますが、C言語ではありません。振る舞いを理解していただきやすくするための仮想言語です。実行できる環境はありません。

「競合」という問題

 ここに、1つのリンゴがあります。そして、2人の人が、そのリンゴの前にいます。ここで2人に向かって「リンゴを食べて良いですよ」とだけ言うと、どうなるでしょうか。お互いに譲り合うか、もしくは取り合いをするでしょう。ここで2人が仲良くリンゴにありつくためには、調停者がいて、どのように分けるかを決めることが必要です。もちろん、2人のうちどちらかが調停者を兼ねてもかまいません。

 並列プログラミングを行うということは、このように、2人以上の人に何らかの作業を依頼することにたとえられます。これらの作業を依頼された人がそれぞれ別個の作業を行うなら、何の問題もありません。しかし、複数の人が同じ資源を操作するようなことがあると、問題が発生します。

 List1は、1000個の文字を格納できるスタックです。

List1.マルチスレッドで問題がある仮想コード
#define ARRAY_MAX 1000
static char array[ARRAY_MAX];
static int index = 0;

int push(char v) {
    if (index < ARRAY_MAX) {
        array[index] = v;
        ++index;
    }
    return index;
}

char pop(void) {
    if (index > 0) {
        return array[index];
        --index;
    }
    return NULL;
}

int howmany(void) {
    return index;
}

 このコードは、シングルスレッドで実行している限り、安全に実行できます。しかし、マルチスレッドでは、安全ではありません。マルチスレッドでは、コードが同時に実行されます。次のように実行がなされたとき、どのようになるでしょうか。なお、これらの実行直前で、indexは999、つまりあと1つなら追加できる状態で、2つ追加しようとしている状況です。

表1
実行前の スレッド1 スレッド2 実行後の
index値 実行行 実行行 index値
999 int push(char v) {   999
999 if (index < ARRAY_MAX) {   999
999 array[index] = v; int push(char v) { 999
999 ++index; if (index < ARRAY_MAX) { 1000
1000 return index; array[index] = v; 1000
1000   ++index; 1001
1001   return index; 1001

 スレッド2のif文でindex値を参照した後、スレッド1のインクリメントが実行され、indexの値が1000となりました。するとスレッド2では、array配列の1001番目の要素にアクセスすることになります。これを実行した結果どうなるかは、実行環境により異なりますが、アプリケーションのどこかで、期待しないエラーが出る可能性が高くなります。

 さて、このコードの問題は何でしょうか。それは、index変数の1つのインスタンスが複数のスレッドで共有されることです。index変数がどのようなアクセススコープを持っていても、関係はありません。複数のスレッドが同じインスタンスを共有すると、問題が発生します。

逐次処理で発生する並列化と同じ問題

(「並列処理とコンテナ:スレッドセーフとは何か」より)

並列プログラミングを行う際には、従来の逐次プログラミングでは考えなかったことを考えなくてはなりません。そのうちの1つが、並列処理で同時にコンテナを操作する時に起こる問題についてです。これはよく「マルチスレッドプログラミングではスレッドセーフなコンテナを使う必要がある」と表現されます。

 インドリ氏のこの書き方は、誤解を招く表現を多く含んでいます。

1)「並列プログラミング」に対する誤解を与える

 「並列プログラミングを行う際には」という表記と、「マルチスレッドプログラミングでは」という表記が混在することにより、並列プログラミングをマルチスレッドプログラミングに限定するような表現がされています。しかし、「並列プログラミング」には「マルチスレッド」以外にも「マルチタスク」があります。もっとも、「マルチタスク」の場合は「プログラミング」という小さな単位ではなく、システムという大きな単位になります。

2)従来の逐次プログラミングというほど、並列プログラミングは新しいわけではない

 「並列プログラミング」には、「マルチスレッド」だけでなく「マルチタスク」が含まれます。マルチタスクはMS-DOSからWindowsに移行したとき、すなわちWindows2.0から発生しており、これは1987年に誕生しています。ただし、完全なマルチタスクOSには1993年のWindows NT 3.1まで待たなければなりません。しかし、UNIXについては、生まれたときから完全なマルチタスクOSでした。

3)並列プログラミングに限った問題ではない

 スレッドクリティカルの根本的な問題は、複数の処理が同じインスタンスを操作することです。これは、並列プログラミングに限った問題ではありません。データベースを扱う場合や、非同期実行を行う場合、一時ファイルやセマフォといった共有メモリなどを扱う場合など、逐次プログラミングであっても同様に発生します。

会員登録無料すると、続きをお読みいただけます

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

次のページ
「競合問題」の解決

修正履歴

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
インテルTBBを通じて学ぶ並列処理連載記事一覧

もっと読む

この記事の著者

はなおかじった(ハナオカジッタ)

わんくま同盟で、ブログを書いています。2004年10月から5年間連続で、Microsoft Most Valueable Professional Award for ASP/ASP.NET を受賞させていただきました。コミュニティの皆様のおかげです。ありがとうございます。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/5077 2010/05/12 22:34
" ); }

おすすめ

アクセスランキング

  1. 1
    デスクトップアプリ開発に必要な「Rust」の文法を理解しよう NEW
  2. 2
    より使いやすくなったPHP 8.4の新機能──クラス定義や言語仕様とデータベース関連の強化ポイント NEW
  3. 3
    テストは増え続ける、でもボトルネックにはできない──テスト効率化の2つのカギを朱峰 錦司氏が解説!
  4. 4
    デスクトップアプリを開発しよう! 「Rust」と「Tauri 2.0」の基本情報と環境整備の仕方を解説
  5. 5
    Google、社内AIエージェント「Google Agentspace」発表 NEW
  1. 6
    アジャイル開発の推進において、必ずしも"すごい人"は必要ない──現場のエンジニアがDevOps推進で実現する組織改革 NEW
  2. 7
    「イテレータ」 ~マンガでプログラミング用語解説
  3. 8
    いいエンジニアになるための2つのポイント ──元Google技術者・石原氏が説く「シリコンバレー流ソフトウェア開発術」
  4. 9
    Fish Shell 4.0 ベータ版リリース、C++からRustに移行 NEW
  5. 10
    Amazon ECSのオブザーバビリティが強化、監視に「Amazon CloudWatch Container Insights」の機能を利用可能に NEW

アクセスランキング

  1. 1
    デスクトップアプリ開発に必要な「Rust」の文法を理解しよう NEW
  2. 2
    より使いやすくなったPHP 8.4の新機能──クラス定義や言語仕様とデータベース関連の強化ポイント NEW
  3. 3
    テストは増え続ける、でもボトルネックにはできない──テスト効率化の2つのカギを朱峰 錦司氏が解説!
  4. 4
    デスクトップアプリを開発しよう! 「Rust」と「Tauri 2.0」の基本情報と環境整備の仕方を解説
  5. 5
    Google、社内AIエージェント「Google Agentspace」発表 NEW
  6. 6
    アジャイル開発の推進において、必ずしも"すごい人"は必要ない──現場のエンジニアがDevOps推進で実現する組織改革 NEW
  7. 7
    「イテレータ」 ~マンガでプログラミング用語解説
  8. 8
    いいエンジニアになるための2つのポイント ──元Google技術者・石原氏が説く「シリコンバレー流ソフトウェア開発術」
  9. 9
    Fish Shell 4.0 ベータ版リリース、C++からRustに移行 NEW
  10. 10
    Amazon ECSのオブザーバビリティが強化、監視に「Amazon CloudWatch Container Insights」の機能を利用可能に NEW
  1. 1
    いいエンジニアになるための2つのポイント ──元Google技術者・石原氏が説く「シリコンバレー流ソフトウェア開発術」
  2. 2
    「CUDA」 ~マンガでプログラミング用語解説
  3. 3
    ITエンジニア本大賞2025、投票締切直前! みんなで選んだ歴代の大賞本を振り返って一挙紹介
  4. 4
    デスクトップアプリを開発しよう! 「Rust」と「Tauri 2.0」の基本情報と環境整備の仕方を解説
  5. 5
    2024年12月に開催される注目のITエンジニア向けカンファレンス5選
  6. 6
    日本在住の英語を話すソフトウェア開発者、年収の中央値は950万円に
  7. 7
    管理職の24.1%、今後管理職を「続けたくない」と回答。理由は「責任やストレス」が最多に
  8. 8
    VSCodeをドキュメント作成に活用――テキストエディタ、Markdownエディタの設定と拡張機能を解説
  9. 9
    2024年の提示年収が高いプログラミング言語は? paiza調査によるランキングが発表
  10. 10
    ランサーズ、「2024年必要とされたスキルランキング」を公開。「Lancers」上のデータを集計

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

メールバックナンバー

アクセスランキング

  1. 1
    デスクトップアプリ開発に必要な「Rust」の文法を理解しよう NEW
  2. 2
    より使いやすくなったPHP 8.4の新機能──クラス定義や言語仕様とデータベース関連の強化ポイント NEW
  3. 3
    テストは増え続ける、でもボトルネックにはできない──テスト効率化の2つのカギを朱峰 錦司氏が解説!
  4. 4
    デスクトップアプリを開発しよう! 「Rust」と「Tauri 2.0」の基本情報と環境整備の仕方を解説
  5. 5
    Google、社内AIエージェント「Google Agentspace」発表 NEW
  1. 6
    アジャイル開発の推進において、必ずしも"すごい人"は必要ない──現場のエンジニアがDevOps推進で実現する組織改革 NEW
  2. 7
    「イテレータ」 ~マンガでプログラミング用語解説
  3. 8
    いいエンジニアになるための2つのポイント ──元Google技術者・石原氏が説く「シリコンバレー流ソフトウェア開発術」
  4. 9
    Fish Shell 4.0 ベータ版リリース、C++からRustに移行 NEW
  5. 10
    Amazon ECSのオブザーバビリティが強化、監視に「Amazon CloudWatch Container Insights」の機能を利用可能に NEW

アクセスランキング

  1. 1
    デスクトップアプリ開発に必要な「Rust」の文法を理解しよう NEW
  2. 2
    より使いやすくなったPHP 8.4の新機能──クラス定義や言語仕様とデータベース関連の強化ポイント NEW
  3. 3
    テストは増え続ける、でもボトルネックにはできない──テスト効率化の2つのカギを朱峰 錦司氏が解説!
  4. 4
    デスクトップアプリを開発しよう! 「Rust」と「Tauri 2.0」の基本情報と環境整備の仕方を解説
  5. 5
    Google、社内AIエージェント「Google Agentspace」発表 NEW
  6. 6
    アジャイル開発の推進において、必ずしも"すごい人"は必要ない──現場のエンジニアがDevOps推進で実現する組織改革 NEW
  7. 7
    「イテレータ」 ~マンガでプログラミング用語解説
  8. 8
    いいエンジニアになるための2つのポイント ──元Google技術者・石原氏が説く「シリコンバレー流ソフトウェア開発術」
  9. 9
    Fish Shell 4.0 ベータ版リリース、C++からRustに移行 NEW
  10. 10
    Amazon ECSのオブザーバビリティが強化、監視に「Amazon CloudWatch Container Insights」の機能を利用可能に NEW
  1. 1
    いいエンジニアになるための2つのポイント ──元Google技術者・石原氏が説く「シリコンバレー流ソフトウェア開発術」
  2. 2
    「CUDA」 ~マンガでプログラミング用語解説
  3. 3
    ITエンジニア本大賞2025、投票締切直前! みんなで選んだ歴代の大賞本を振り返って一挙紹介
  4. 4
    デスクトップアプリを開発しよう! 「Rust」と「Tauri 2.0」の基本情報と環境整備の仕方を解説
  5. 5
    2024年12月に開催される注目のITエンジニア向けカンファレンス5選
  6. 6
    日本在住の英語を話すソフトウェア開発者、年収の中央値は950万円に
  7. 7
    管理職の24.1%、今後管理職を「続けたくない」と回答。理由は「責任やストレス」が最多に
  8. 8
    VSCodeをドキュメント作成に活用――テキストエディタ、Markdownエディタの設定と拡張機能を解説
  9. 9
    2024年の提示年収が高いプログラミング言語は? paiza調査によるランキングが発表
  10. 10
    ランサーズ、「2024年必要とされたスキルランキング」を公開。「Lancers」上のデータを集計