<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Yukun&#039;s Blog &#187; pthread</title>
	<atom:link href="http://www.yukun.info/blog/tag/pthread/feed" rel="self" type="application/rss+xml" />
	<link>http://www.yukun.info</link>
	<description>難しいことは分かりやすく、簡単なことは面白く紹介</description>
	<lastBuildDate>Thu, 26 Jan 2012 03:33:59 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>C++, pthread: スレッドの同期と排他制御 &#8211; MutexとCondition Variable</title>
		<link>http://www.yukun.info/blog/2008/10/c-pthread-mutex-condition-variable.html</link>
		<comments>http://www.yukun.info/blog/2008/10/c-pthread-mutex-condition-variable.html#comments</comments>
		<pubDate>Tue, 28 Oct 2008 04:00:47 +0000</pubDate>
		<dc:creator>yukun</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Multithread]]></category>
		<category><![CDATA[pthread]]></category>
		<category><![CDATA[Synchronization]]></category>

		<guid isPermaLink="false">http://www.yukun.info/?p=1224</guid>
		<description><![CDATA[以前、Boostライブラリを用いたスレッドの同期と排他制御を取り上げましたが、今記事はそれのpthreadバージョンです（似せただけです）。pthreadライブラリ自体はC言語から扱えますが、今回はstaticなメンバ関 &#8230; <a href="http://www.yukun.info/blog/2008/10/c-pthread-mutex-condition-variable.html">Continue reading <span class="meta-nav">&#8594;</span></a><p><a href="http://www.yukun.info/blog/2008/10/c-pthread-mutex-condition-variable.html">C++, pthread: スレッドの同期と排他制御 &#8211; MutexとCondition Variable</a> is a post from: <a href="http://www.yukun.info">Yukun&#039;s Blog</a></p>
]]></description>
			<content:encoded><![CDATA[<p>以前、<a href="http://www.yukun.info/blog/2008/07/boost-thread-mutex-condition.html" title="C++, boost::thread : スレッドの同期と排他制御 - mutex、conditionクラス - Yukun's Blog">Boostライブラリを用いたスレッドの同期と排他制御</a>を取り上げましたが、今記事はそれのpthreadバージョンです（似せただけです）。pthreadライブラリ自体はC言語から扱えますが、今回はstaticなメンバ関数を別スレッドで動かす練習も兼ねてC++で書いてみました。</p>
<h2>ソースコード</h2>
<pre>
#include &lt;iostream&gt;
using namespace std;

#include &lt;stdio.h&gt;
#include &lt;pthread.h&gt;

#define BUFFER_NUM 100
#define WAIT_NUM 1000000
#define LOOP_NUM 100

class HandleData {
public:
  HandleData()
  : index_(0), channel_array_len_(sizeof(channel_array_)/sizeof(channel_array_[0])), num_data_(0) {
    access_lock_ = PTHREAD_MUTEX_INITIALIZER;
    access_threshold_ = PTHREAD_COND_INITIALIZER;
  }

  // データの追加
  void putData(int n) {
    pthread_mutex_lock(&amp;access_lock_); // スレッドにロックをかける
    while (index_ &gt;= channel_array_len_) {
      printf(&quot;putData(): waitn&quot;);
      pthread_cond_wait(&amp;access_threshold_, &amp;access_lock_);
      // このスレッドを一時停止しロックを解除する（getData側のpthread_cond_signalが呼ばれるまで）
    }
    int i = index_;
    channel_array_[index_++] = n; // スレッドセーフなデータ格納
    printf(&quot;put: %2d in channel_array_[%2d]n&quot;, n, i);
    pthread_cond_signal(&amp;access_threshold_);
    pthread_mutex_unlock(&amp;access_lock_); // スレッドのロックを解除
  }

  // データの取得
  int getData() {
    pthread_mutex_lock(&amp;access_lock_);
    while (index_ &lt;= 0) {
      printf(&quot;getData(): waitn&quot;);
      pthread_cond_wait(&amp;access_threshold_, &amp;access_lock_);
      // このスレッドを一時停止しロックを解除する（putData側のpthread_cond_signalが呼ばれるまで）
    }
    num_data_ = channel_array_[--index_]; // スレッドセーフなデータ取得
    printf(&quot;get: %2d in channel_array_[%2d]n&quot;, num_data_, index_);
    pthread_cond_signal(&amp;access_threshold_);
    pthread_mutex_unlock(&amp;access_lock_);
    return num_data_;
  }

  // データを格納する関数(スレッド)
  static void *runPut(void *hd) {
    int wait_num = WAIT_NUM;
    HandleData *phd = reinterpret_cast&lt;handleData*&gt;(hd);
    for (int i = 0; i &lt; LOOP_NUM; i++) {
      phd-&gt;putData(i);
      while (--wait_num); // 空回しで時間稼ぎ
      wait_num = WAIT_NUM;
    }
    return NULL;
  }

  // データを取得する関数(スレッド)
  static void *runGet(void *hd) {
    HandleData *phd = reinterpret_cast&lt;handleData*&gt;(hd);
    for (int i = 0; i &lt; LOOP_NUM; i++) {
      phd-&gt;getData();
    }
    return NULL;
  }

private:
  pthread_mutex_t access_lock_; // 排他制御を行う変数(lock, unlock)
  pthread_cond_t access_threshold_; // 状態変数(waitしてlockを外す用途)
  volatile int index_;
  int channel_array_[BUFFER_NUM]; // putData()、getData()からアクセスされる変数
  const int channel_array_len_;
  int num_data_;
};

int main()
{
  pthread_t thr_put;
  pthread_t thr_get;
  HandleData hd;
  // スレッドの生成(走らせるのはstaticメンバ関数)
  pthread_create(&amp;thr_put, NULL, HandleData::runPut, reinterpret_cast&lt;void*&gt;(&amp;hd));
  pthread_create(&amp;thr_get, NULL, HandleData::runGet, reinterpret_cast&lt;void*&gt;(&amp;hd));

  pthread_join(thr_put, NULL);
  pthread_join(thr_get, NULL);

  return 0;
}
</pre>
<p>あまりこういった書き方はしないのだけれど。</p>
<h2>実行結果の一例</h2>
<pre>
put:  0 in channel_array_[ 0]
put:  1 in channel_array_[ 1]
put:  2 in channel_array_[ 2]
put:  3 in channel_array_[ 3]
get:  3 in channel_array_[ 3]
get:  2 in channel_array_[ 2]
＜中略＞
put: 96 in channel_array_[ 0]
get: 96 in channel_array_[ 0]
getData(): wait
put: 97 in channel_array_[ 0]
get: 97 in channel_array_[ 0]
getData(): wait
put: 98 in channel_array_[ 0]
get: 98 in channel_array_[ 0]
getData(): wait
put: 99 in channel_array_[ 0]
get: 99 in channel_array_[ 0]
</pre>
<h2>pthreadで相互排他を行う際の注意点</h2>
<p>boostのmutex::scoped_lockクラスであればデストラクタにロックの解除を任せられるので管理が楽ですが、pthreadでは「ロックする」、「ロック解除」の2ステップを必ず書かなければなりません。なのでロック中に予期せぬ例外やエラーの為関数などのスコープを脱する際もpthread_mutex_unlock()をし忘れていないか等の注意が必要です。<br />
<h4>関連すると思われる記事：</h4>
<ul class="similar-posts">
<li><a href="http://www.yukun.info/blog/2008/07/boost-thread-mutex-condition.html" rel="bookmark" title="2008年7月25日">C++, boost::thread : スレッドの同期と排他制御 &#8211; mutex、conditionクラス</a></li>
<li><a href="http://www.yukun.info/blog/2008/07/boost-thread-group-create.html" rel="bookmark" title="2008年7月24日">C++, boost::thread : スレッドグループの生成と実行</a></li>
<li><a href="http://www.yukun.info/blog/2008/07/boost-thread-create-run.html" rel="bookmark" title="2008年7月8日">C++, boost::thread : スレッドの生成と実行</a></li>
<li><a href="http://www.yukun.info/blog/2008/09/cause-java-io-stream-corrupted-exception.html" rel="bookmark" title="2008年9月4日">java.io.StreamCorruptedExceptionが発生した原因とその解決策の一例</a></li>
<li><a href="http://www.yukun.info/blog/2009/03/note-of-the-day-2009-03-22.html" rel="bookmark" title="2009年3月22日">Note of the Day &#8211; 2009-03-22</a></li>
</ul>
<p><!-- Similar Posts took 6.856 ms --></p>
<p><a href="http://www.yukun.info/blog/2008/10/c-pthread-mutex-condition-variable.html">C++, pthread: スレッドの同期と排他制御 &#8211; MutexとCondition Variable</a> is a post from: <a href="http://www.yukun.info">Yukun&#039;s Blog</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.yukun.info/blog/2008/10/c-pthread-mutex-condition-variable.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

