<?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; C/C++</title>
	<atom:link href="http://www.yukun.info/blog/category/cc/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 8.463 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>
		<item>
		<title>C++, boost::thread : スレッドの同期と排他制御 &#8211; mutex、conditionクラス</title>
		<link>http://www.yukun.info/blog/2008/07/boost-thread-mutex-condition.html</link>
		<comments>http://www.yukun.info/blog/2008/07/boost-thread-mutex-condition.html#comments</comments>
		<pubDate>Thu, 24 Jul 2008 15:00:34 +0000</pubDate>
		<dc:creator>yukun</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Boost]]></category>
		<category><![CDATA[Multithread]]></category>
		<category><![CDATA[Synchronization]]></category>

		<guid isPermaLink="false">http://trumpcode.yukun.info/?p=201</guid>
		<description><![CDATA[複数のスレッドから1つの変数にアクセスする際、システム側のスレッドスケジューリング次第で、予期せぬ書き換えが起こってしまう場合があります。その為、ある1つのスレッドが変数にアクセスしている際は他のスレッドをブロックする排 &#8230; <a href="http://www.yukun.info/blog/2008/07/boost-thread-mutex-condition.html">Continue reading <span class="meta-nav">&#8594;</span></a><p><a href="http://www.yukun.info/blog/2008/07/boost-thread-mutex-condition.html">C++, boost::thread : スレッドの同期と排他制御 &#8211; mutex、conditionクラス</a> is a post from: <a href="http://www.yukun.info">Yukun&#039;s Blog</a></p>
]]></description>
			<content:encoded><![CDATA[<p>複数のスレッドから1つの変数にアクセスする際、システム側のスレッドスケジューリング次第で、予期せぬ書き換えが起こってしまう場合があります。その為、ある1つのスレッドが変数にアクセスしている際は他のスレッドをブロックする排他制御やスレッドの同期を行う必要があります。C++でJavaのsynchronizedメソッド/ブロックと同じような記法でクリティカルセクションを実装する方法の1つにboost::threadライブラリのmutexとconditionクラスがあります。</p>
<h2>mutex クラスの使い方</h2>
<p>スレッドの排他制御を実現できます。具体的な使い方は、mutexインスタンスをmutex::scoped_lockクラスのコンストラクタの引数に指定し、そのインスタンスを取得することでロックをかけられます。あるスレッドが上の処理を以ってmutexインスタンスにロックをかけた場合、その他のスレッドは再度同一のmutexインスタンスにロックをかけられないようになっており、その他のスレッドはscoped_lockのコンストラクタ途中で待たされます。</p>
<p>mutexインスタンスのロック解除は、ロックをかけたスレッドがscoped_lockインスタンスのデストラクタを実行することで完了します。</p>
<h2>condition クラスの使い方</h2>
<p>次に、複数のスレッドを同期させる処理について。例えば、あるスレッドが排他的にある変数にアクセスしようとするが、その前にif文を用いて「Wait! そのアクセスちょっと待った！しばらく他のスレッドの処理を待て！」みたいな処理を行いたい場合。そのスレッドは既にmutex変数でロックを取得していますが、「待ち」に入る際はロックを解除する必要があります。</p>
<p>上述のような処理を実現するのがconditionクラスです。メンバ関数のwait()に引数にmutexインスタンスを指定することで、そのスレッドはロックを解除し一時停止します。他のスレッドがnotify_all()を実行すると、一時停止中の全てのスレッドが実行可能状態になります。これによって、スレッドの同期を実現します。</p>
<h2>実際にどんな挙動か確かめよう</h2>
<p>上の説明は以下のサンプルと実行結果を先に確認した後の方がしっくりくるかもしれません。</p>
<h3>ソースコード</h3>
<pre>
#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;boost/thread.hpp&gt;
#include &lt;boost/bind.hpp&gt;
using namespace std;
using namespace boost;

class HandleData {
 public:
  HandleData()
    : index_(0), iarr_len_(sizeof(iarr_)/sizeof(iarr_[0])), num_data_(0){}

  // データの追加
  void putData(int n) {
    // mutexインスタンスにロックをかける
    mutex::scoped_lock look(thread_sync_);
    while (index_ &gt;= iarr_len_) {
      printf(&quot;[putData] waitn&quot;);
      // 引数のmutexインスタンスのロックを解除する。
      // notify_all()などが呼ばれるまでこのスレッドを一時停止する
      thread_state_.wait(thread_sync_);
    }
    printf(&quot;put: %d in iarr_[%d]n&quot;, n, index_);
    iarr_[index_++] = n;
    int loop = 1000000;
    while(loop--) ; // 空回し用
    thread_state_.notify_all();
  } // lockのデストラクタが呼ばれてロック解除(lookインスタンスのスコープ切れ)

  // データの取得
  int getData() {
    // putData()と同じくiarr_にスレッドセーフでアクセスする為にロックをかける
    mutex::scoped_lock look(thread_sync_);
    while (index_ &lt;= 0) { // putData側のthread_state_.notify_all();が実行されるまで待つ
      printf(&quot;[getData] waitn&quot;);
      thread_state_.wait(thread_sync_);
    }
    num_data_ = iarr_[--index_];
    printf(&quot;get: %d in iarr_[%d]n&quot;, num_data_, index_);
    thread_state_.notify_all();
    return num_data_;
  } // lookのデストラクタでロック解除

 private:
  mutex thread_sync_;
  condition thread_state_;
  volatile int index_;
  int iarr_[100]; // putData()、getData()からアクセスされる変数
  const unsigned int iarr_len_;
  int num_data_;
};

void threadPut(HandleData *hd) {
  const unsigned int NUM_LOOP = 100;
  for (int i = 0; i &lt; NUM_LOOP; i++) {
    hd-&gt;putData(i);
  }
}

void threadGet(HandleData *hd) {
  const unsigned int NUM_LOOP = 100;
  for (int i = 0; i &lt; NUM_LOOP; i++) {
    hd-&gt;getData();
  }
}

int main()
{
  HandleData hd;
  thread thr_put(bind(&amp;threadPut, &amp;hd));
  thread thr_get(bind(&amp;threadGet, &amp;hd));
  thr_put.join();
  thr_get.join();
  return 0;
}
</pre>
<h3>実行結果の一例</h3>
<p>実行する環境によって、出力結果は変化します(格納・出力順序など)。</p>
<pre>
put: 0 in iarr_[0]
get: 0 in iarr_[0]
put: 1 in iarr_[0]
get: 1 in iarr_[0]
＜中略＞
get: 12 in iarr_[1]
get: 11 in iarr_[0]
[getData] wait
put: 13 in iarr_[0]
put: 14 in iarr_[1]
get: 14 in iarr_[1]
get: 13 in iarr_[0]
[getData] wait
put: 15 in iarr_[0]
put: 16 in iarr_[1]
＜中略＞
get: 95 in iarr_[0]
[getData] wait
put: 97 in iarr_[0]
put: 98 in iarr_[1]
get: 98 in iarr_[1]
get: 97 in iarr_[0]
[getData] wait
put: 99 in iarr_[0]
get: 99 in iarr_[0]
</pre>
<h3>volatile 修飾子の必要性</h3>
<p>52行目のメンバ変数のindexの宣言</p>
<p><code>volatile int index_;</code></p>
<p>volatile(揮発性)接頭語がつくと、コンパイラによる最適化を防ぐことができます。これによって、プログラムはindex_を読み取る際は必ずメモリから読みにいきます。これは変数が複数スレッドから常に書き換えられても、必ずそれが反映されるということです。</p>
<p>このサンプルでは付けなくても最適化によるバグの発生はなさそうかな&#8230;?</p>
<h3>リファレンス</h3>
<ul>
<li><a href="http://www.boost.org/doc/libs/1_35_0/doc/html/thread.html" title="Boost C++ Libraries - Chapter 17. Thread">Boost C++ Libraries &#8211; Chapter 17. Thread</a>
<ul>
<li><a href="http://www.boost.org/doc/libs/1_35_0/doc/html/thread/synchronization.html#thread.synchronization.mutex_types" title="Boost C++ Libraries - Synchronization">Boost C++ Libraries &#8211; Synchronization</a></li>
</ul>
</li>
</ul>
<h4>関連すると思われる記事：</h4>
<ul class="similar-posts">
<li><a href="http://www.yukun.info/blog/2008/10/c-pthread-mutex-condition-variable.html" rel="bookmark" title="2008年10月28日">C++, pthread: スレッドの同期と排他制御 &#8211; MutexとCondition Variable</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 7.829 ms --></p>
<p><a href="http://www.yukun.info/blog/2008/07/boost-thread-mutex-condition.html">C++, boost::thread : スレッドの同期と排他制御 &#8211; mutex、conditionクラス</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/07/boost-thread-mutex-condition.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>C++, boost::thread : スレッドグループの生成と実行</title>
		<link>http://www.yukun.info/blog/2008/07/boost-thread-group-create.html</link>
		<comments>http://www.yukun.info/blog/2008/07/boost-thread-group-create.html#comments</comments>
		<pubDate>Wed, 23 Jul 2008 15:00:53 +0000</pubDate>
		<dc:creator>yukun</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Boost]]></category>
		<category><![CDATA[Multithread]]></category>

		<guid isPermaLink="false">http://trumpcode.yukun.info/?p=188</guid>
		<description><![CDATA[同じような処理を行うスレッドが複数ある場合は、それらをスレッドグループでまとめると、スレッドへの操作がやり易くなります。スレッドグループへの登録には、boost::thread ライブラリの thread_group ク &#8230; <a href="http://www.yukun.info/blog/2008/07/boost-thread-group-create.html">Continue reading <span class="meta-nav">&#8594;</span></a><p><a href="http://www.yukun.info/blog/2008/07/boost-thread-group-create.html">C++, boost::thread : スレッドグループの生成と実行</a> is a post from: <a href="http://www.yukun.info">Yukun&#039;s Blog</a></p>
]]></description>
			<content:encoded><![CDATA[<p>同じような処理を行うスレッドが複数ある場合は、それらをスレッドグループでまとめると、スレッドへの操作がやり易くなります。スレッドグループへの登録には、boost::thread ライブラリの thread_group クラスを用いて、メンバ関数 create_thread() の引数にマルチスレッドで実行したい関数のアドレスを指定します。</p>
<p>それでは下記のサンプルで実際にその過程と実行結果を確認してみましょう。</p>
<h3>ソースコード</h3>
<pre>
#include &lt;iostream&gt;
#include &lt;boost/bind.hpp&gt;
#include &lt;boost/thread.hpp&gt;
using namespace std;
using namespace boost;

// マルチスレッドで実行する関数
void run(const char thr_name) {
  int count = 0;
  while(1) {
    if (++count % 100000000 == 0) // 空回り用の if 文
      cout &lt;&lt; &quot;Thread-&quot; &lt;&lt; thr_name &lt;&lt; &quot;: No.&quot; &lt;&lt; count &lt;&lt; endl;
  }
}

int main()
{
  const char chs[] = {&#039;A&#039;, &#039;B&#039;, &#039;C&#039;, &#039;D&#039;}; // 生成スレッドの名前の配列
  const int NUM_THREAD = sizeof(chs) / sizeof(chs[0]); // 配列の要素数の算出

  // スレッドグループの生成と実行開始
  thread_group thr_grp;
  for (int i = 0; i &lt; NUM_THREAD; ++i) {
    thr_grp.create_thread(bind(&amp;run, chs[i])); // create_thread()でrun()を別スレッドで実行
  }
  // join_all()で全スレッドの終了を待つ
  thr_grp.join_all();
  return 0;
}
</pre>
<h3>実行結果の一例</h3>
<p>実行する環境によって、出力結果は変化します(順序など)。</p>
<pre>
Thread-B: No.100000000
Thread-A: No.100000000
Thread-C: No.100000000
Thread-D: No.100000000
Thread-B: No.200000000
Thread-A: No.200000000
Thread-C: No.200000000
Thread-D: No.200000000
Thread-B: No.300000000
Thread-A: No.300000000
Thread-C: No.300000000
Thread-D: No.300000000
Thread-B: No.400000000
Thread-A: No.400000000
＜略＞
</pre>
<h3>リファレンス</h3>
<ul>
<li><a href="http://www.boost.org/doc/libs/1_35_0/doc/html/thread.html" title="Boost C++ Libraries - Chapter 17. Thread">Boost C++ Libraries &#8211; Chapter 17. Thread</a>
<ul>
<li><a href="http://www.boost.org/doc/libs/1_35_0/doc/html/thread/thread_management.html#thread.thread_management.threadgroup" title="Boost C++ Libraries - Thread Management">Boost C++ Libraries &#8211; Thread Management</a></li>
</ul>
</li>
</ul>
<h4>関連すると思われる記事：</h4>
<ul class="similar-posts">
<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/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/10/c-pthread-mutex-condition-variable.html" rel="bookmark" title="2008年10月28日">C++, pthread: スレッドの同期と排他制御 &#8211; MutexとCondition Variable</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 12.170 ms --></p>
<p><a href="http://www.yukun.info/blog/2008/07/boost-thread-group-create.html">C++, boost::thread : スレッドグループの生成と実行</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/07/boost-thread-group-create.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C++, boost::thread : スレッドの生成と実行</title>
		<link>http://www.yukun.info/blog/2008/07/boost-thread-create-run.html</link>
		<comments>http://www.yukun.info/blog/2008/07/boost-thread-create-run.html#comments</comments>
		<pubDate>Mon, 07 Jul 2008 15:00:50 +0000</pubDate>
		<dc:creator>yukun</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Boost]]></category>
		<category><![CDATA[Multithread]]></category>

		<guid isPermaLink="false">http://www.yukun.info/trump/?p=135</guid>
		<description><![CDATA[C/C++でスレッドを扱う場合は、プラットフォームによって使用するライブラリが違います。 Windows なら Windows API の thread で、 UNIX や Linux 系ならば pthread ライブラ &#8230; <a href="http://www.yukun.info/blog/2008/07/boost-thread-create-run.html">Continue reading <span class="meta-nav">&#8594;</span></a><p><a href="http://www.yukun.info/blog/2008/07/boost-thread-create-run.html">C++, boost::thread : スレッドの生成と実行</a> is a post from: <a href="http://www.yukun.info">Yukun&#039;s Blog</a></p>
]]></description>
			<content:encoded><![CDATA[<p>C/C++でスレッドを扱う場合は、プラットフォームによって使用するライブラリが違います。 Windows なら Windows API の thread で、 UNIX や Linux 系ならば pthread ライブラリ等を使用します。プラットフォーム依存するコードは可搬性に難があり、解決策の1つとしてプリコンパイルで依存部分をプラットフォームに合わせたライブラリを選択してコンパイルする方法があります。</p>
<p>boost ライブラリの boost::thread は、上のような処理をラップして共通のインターフェイスとして実装されています。</p>
<p>boost/thread.hppの一部</p>
<pre>
#if defined(BOOST_THREAD_PLATFORM_WIN32)
#include &lt;boost/thread/win32/thread.hpp&gt;
#elif defined(BOOST_THREAD_PLATFORM_PTHREAD)
#include &lt;boost/thread/pthread/thread.hpp&gt;
#else
#error &quot;Boost threads unavailable on this platform&quot;
#endif
</pre>
<p>これによって、 boost がインストールされている OS ならば、同じコードでコンパイルすることが出来ます。さて、それでは boost::thread を使って基本的なスレッドの生成と実行を、以下の三つのパターンで確認してみます。</p>
<ul>
<li>引数なし関数をマルチスレッドで実行</li>
<li>引数付き関数をマルチスレッドで実行</li>
<li>メンバ関数をマルチスレッドで実行</li>
</ul>
<h2>引数なし関数をマルチスレッドで実行</h2>
<h3>ソースコード</h3>
<pre>
#include &lt;iostream&gt;
#include &lt;boost/thread.hpp&gt;
using namespace std;
using namespace boost;

// 引数なし関数をマルチスレッドで実行

const int kCount =  100000000;
const int kInterval = 1000000;

void PrintHello() {
  for(int i = 0; i != kCount; ++i)
    if (!(i % kInterval)) cout &lt;&lt; &quot;Hello &quot;;
}

void PrintWorld() {
  for(int i = 0; i != kCount; ++i)
    if (!(i % kInterval)) cout &lt;&lt; &quot;World! &quot;;
}

int main() {
  thread thr_hello(&amp;PrintHello); // PrintHello関数を実行するスレッドの生成、実行
  thread thr_world(&amp;PrintWorld);

  thr_hello.join(); // thr_helloが走らせているスレッドの終了を待つ
  thr_world.join();
  return 0;
}
</pre>
<h3>実行結果の一部抜粋</h3>
<p><code><br />
Hello World! Hello Hello World! Hello World! Hello World! Hello World! World! Hello World! Hello World! Hello World! Hello World! Hello World! World!<br />
</code></p>
<p>13行目: PrintHello() の for ループで kInteral を用いて空回りの負荷をある程度与えることで、スレッドの切り替え(スレッドスケジューリング)を出力に反映させやすくしています。仮に、単なるforループだと、マシン性能が高い場合スレッドの切り替え前に関数の実行が終了してしまう場合もありマルチスレッドか否かの確認がとり難いです。</p>
<p>23行目: thread クラスのインスタンスを生成しそのコンストラクタに、0引数の関数のアドレスを渡すことで、その関数を走らせるスレッドを生成、実行しています。</p>
<p>ここで、関数アドレスを表す表記は&#038;関数名ですが、この<strong>アンパサンド「&#038;」は省略できます</strong>。実際に確認しますと、</p>
<pre>cout <<  PrintHello << endl;
cout << &#038;PrintHello << endl;</pre>
<p>の出力結果は、</p>
<pre>003B17A8
003B17A8</pre>
<p>となります。実行する環境によって上の数値は変わりますが、ここで大事なのは二つの出力が同値である、すなわち「<strong>関数名＝＝&#038;関数名＝＝関数のアドレス</strong>」ということです。</p>
<p>余談ですが、関数アドレスを格納する関数ポインタを引数として渡すことも勿論可能です。例えば、</p>
<pre>void (*fp)(void) = PrintHello; // 関数のアドレスを指す関数ポインタを宣言
thread thr_fp(fp); // ポインタが指すアドレスにある関数を走らせるスレッドを生成、実行</pre>
<p>とも書けます。さて、次に引数をとる関数のスレッドの生成、実行方法を確認しましょう。</p>
<h2>引数付き関数をマルチスレッドで実行</h2>
<h3>ソースコード</h3>
<pre>
#include &lt;iostream&gt;
#include &lt;boost/thread.hpp&gt;
#include &lt;boost/bind.hpp&gt;
using namespace std;
using namespace boost;

// 引数付き関数をマルチスレッドで実行

const int kCount =  100000000;
const int kInterval = 1000000;

void PrintString(const char *str) {
  for(int i = 0; i != kCount; ++i)
    if (!(i % kInterval)) cout &lt;&lt; str;
}

int main() {
  const char *kHello = &quot;Hello &quot;;
  const char *kWorld = &quot;World! &quot;;

  thread thr_hello(bind(&amp;PrintString, kHello));
  thread thr_world(bind(&amp;PrintString, kWorld));

  thr_hello.join();
  thr_world.join();
  return 0;
}
</pre>
<h3>実行結果の一部抜粋</h3>
<p><code><br />
Hello World! Hello Hello World! Hello World! Hello World! Hello World! World! Hello World! Hello World! Hello World! Hello World! Hello World! World!<br />
</code></p>
<p>21行目: thread クラスのコンストラクタには<strong>関数オブジェクトも渡せる</strong>ので、 <strong>boost::bind</strong> を用いて、その第二引数にPrintString 関数に渡したい引数を指定して、関数オブジェクトを生成しています。</p>
<p>さて、2つのスレッドの生成法を確認しましたが、 Java や他のオブジェクト指向をサポートしている言語を使い慣れている人には、違和感のある書き方だったかもしれません。私は「引数よりメンバ変数の呼び出しの方がいい」「C++ならオブジェクト指向だよね」と脊髄反射的に思ったり。<br />
ということで最後は、
</p>
<h2>メンバ関数をマルチスレッドで実行</h2>
<h3>ソースコード</h3>
<pre>
#include &lt;iostream&gt;
#include &lt;boost/thread.hpp&gt;
#include &lt;boost/bind.hpp&gt;
using namespace std;
using namespace boost;

// メンバ関数をマルチスレッドで実行

class PrintMessage {
 public:
  PrintMessage(const char* msg)
    :kMessage_(msg), kCount_(100000000), kInterval_(1000000) {}
  void run();

 private:
  const int kCount_;
  const int kInterval_;
  const char *kMessage_;
};

void PrintMessage::run() {
  for(int i = 0; i != kCount_; ++i)
    if (!(i % kInterval_)) cout &lt;&lt; kMessage_;
}

int main() {
  PrintMessage hello(&quot;Hello &quot;);
  PrintMessage world(&quot;World! &quot;);

  thread thr_hello(bind(&amp;PrintMessage::run, &amp;hello));
  thread thr_world(bind(&amp;PrintMessage::run, &amp;world));

  thr_hello.join();
  thr_world.join();
  return 0;
}
</pre>
<h3>実行結果の一部抜粋</h3>
<p><code><br />
Hello World! Hello Hello World! Hello World! Hello World! Hello World! World! Hello World! Hello World! Hello World! Hello World! Hello World! World!<br />
</code></p>
<p>おー、盛り上がってきましたね。</p>
<h2>リファレンス</h2>
<p><a href="http://www.boost.org/doc/libs/1_31_0/libs/thread/doc/thread.html#class-thread">Boost C++ Libraries - Boost.Threads - &lt;boost/thread.hpp&gt;</a></p>
<h4>関連すると思われる記事：</h4>
<ul class="similar-posts">
<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-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/10/c-pthread-mutex-condition-variable.html" rel="bookmark" title="2008年10月28日">C++, pthread: スレッドの同期と排他制御 &#8211; MutexとCondition Variable</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 8.931 ms --></p>
<p><a href="http://www.yukun.info/blog/2008/07/boost-thread-create-run.html">C++, boost::thread : スレッドの生成と実行</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/07/boost-thread-create-run.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>OpenGL: ポリゴンで円の描画</title>
		<link>http://www.yukun.info/blog/2008/06/opengl-circle.html</link>
		<comments>http://www.yukun.info/blog/2008/06/opengl-circle.html#comments</comments>
		<pubDate>Thu, 19 Jun 2008 15:00:00 +0000</pubDate>
		<dc:creator>yukun</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[C language]]></category>
		<category><![CDATA[Graphics]]></category>
		<category><![CDATA[OpenGL]]></category>

		<guid isPermaLink="false">http://www.yukun.info/trump/19700101/%e3%83%9d%e3%83%aa%e3%82%b4%e3%83%b3%e3%81%a7%e5%86%86%e3%81%ae%e6%8f%8f%e7%94%bb</guid>
		<description><![CDATA[円周上の座標(x, y)×n個を計算しその点を結ぶことによって描画します。nを分割数とすると、nに比例して円は滑らかになります。 実行結果 分割数: 15(ちょっとカクカクしてる) 分割数: 100 コード // Ope &#8230; <a href="http://www.yukun.info/blog/2008/06/opengl-circle.html">Continue reading <span class="meta-nav">&#8594;</span></a><p><a href="http://www.yukun.info/blog/2008/06/opengl-circle.html">OpenGL: ポリゴンで円の描画</a> is a post from: <a href="http://www.yukun.info">Yukun&#039;s Blog</a></p>
]]></description>
			<content:encoded><![CDATA[<p>円周上の座標(x, y)×n個を計算しその点を結ぶことによって描画します。nを分割数とすると、nに比例して円は滑らかになります。</p>
<h3>実行結果</h3>
<ul>
<li>分割数: 15(ちょっとカクカクしてる)</li>
</ul>
<p><a href="http://www.yukun.info/wp-content/uploads/circleP15.gif"><img src="http://www.yukun.info/wp-content/uploads/circleP15.gif" alt="OpenGL: ポリゴンで円の描画(分割数:15)" title="circleP15" width="416" height="437" class="size-full wp-image-1519" /></a><br />
</p>
<ul>
<li>分割数: 100</li>
</ul>
<p><a href="http://www.yukun.info/wp-content/uploads/circleP100.gif"><img src="http://www.yukun.info/wp-content/uploads/circleP100.gif" alt="OpenGL: ポリゴンで円の描画(分割数:100)" title="circleP100" width="416" height="437" class="size-full wp-image-1520" /></a></p>
<h3>コード</h3>
<pre>
// OpenGLで円の描画
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;gl/glut.h&gt;
#include &lt;gl/gl.h&gt;
#include &lt;math.h&gt;

#define M_PI 3.14159265358979 // 円周率
#define PART 100 // 分割数

void display(void)
{
  int i, n = PART;
  float x, y, r = 0.5;
  double rate;

  glClear(GL_COLOR_BUFFER_BIT); // ウィンドウの背景をglClearColor()で指定された色で塗りつぶす
  glColor3f(1.0, 1.0, 1.0); // 描画物体に白色を設定
  glBegin(GL_POLYGON); // ポリゴンの描画
  // 円を描画
  for (i = 0; i &lt; n; i++) {
    // 座標を計算
    rate = (double)i / n;
    x = r * cos(2.0 * M_PI * rate);
    y = r * sin(2.0 * M_PI * rate);
    glVertex3f(x, y, 0.0); // 頂点座標を指定
  }
  glEnd(); // ポリゴンの描画終了
  glFlush(); // OpenGLのコマンドを強制的に実行(描画終了)
}

void init(char *name)
{
  int width = 400, height = 400; // ウィンドウサイズ
  int w_window = glutGet(GLUT_SCREEN_WIDTH), h_window = glutGet(GLUT_SCREEN_HEIGHT); // デスクトップのサイズ
  int w_mid = (w_window-width)/2, h_mid = (h_window-height)/2; // デスクトップの中央座標

  glutInitWindowPosition(w_mid, h_mid);
  glutInitWindowSize(width, height);
  glutInitDisplayMode(GLUT_RGBA); // 色の指定にRGBAモードを使用
  glutCreateWindow(name);
  glClearColor(0.0, 0.0, 0.0, 1.0); // ウィンドウの背景色の指定
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); // 座標系を設定(平行投影)
}

int main(int argc, char **argv)
{
  glutInit(&amp;argc, argv); // glutの初期化
  init(argv[0]);
  glutDisplayFunc(display); // ディスプレイコールバック関数の指定
  glutMainLoop(); // イベント待ちループ
  return 0;
}
</pre>
<p>そういえば、リアルタイム処理などではポリゴンの数を抑えることで処理速度を稼いでましたね。</p>
<p>参考サイト: <a href="http://www.wakayama-u.ac.jp/~tokoi/opengl/libglut.html#5.2" title="GLUTによる「手抜き」OpenGL入門" target="_blank">GLUTによる「手抜き」OpenGL入門</a></p>
<h4>関連すると思われる記事：</h4>
<ul class="similar-posts">
<li><a href="http://www.yukun.info/blog/2008/01/x-window-system-color.html" rel="bookmark" title="2008年1月3日">X Window System 上での描画色の変更</a></li>
<li><a href="http://www.yukun.info/blog/2008/01/decimal-to-binary.html" rel="bookmark" title="2008年1月13日">10進数を2進数に変換表示するC言語プログラム</a></li>
<li><a href="http://www.yukun.info/blog/2009/02/java-swing-jcomponent-drawing-line.html" rel="bookmark" title="2009年2月21日">Java, Swing: JComponentのGraphicsオブジェクトを用いて直線を描画</a></li>
<li><a href="http://www.yukun.info/blog/2008/10/actionscript-paint-flash-flex-button.html" rel="bookmark" title="2008年10月14日">AS3でお絵かきFlashを作る (2)ボタン作成 &#8211; Flexコンポーネントの導入</a></li>
<li><a href="http://www.yukun.info/blog/2008/10/actionscript-paint-flash-flex-draw-tool.html" rel="bookmark" title="2008年10月19日">AS3でお絵かきFlashを作る (3)図形描画と配置選択ツールの追加</a></li>
</ul>
<p><!-- Similar Posts took 7.103 ms --></p>
<p><a href="http://www.yukun.info/blog/2008/06/opengl-circle.html">OpenGL: ポリゴンで円の描画</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/06/opengl-circle.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>3種類の括弧の対応をチェックするC言語プログラム</title>
		<link>http://www.yukun.info/blog/2008/02/check-syntax.html</link>
		<comments>http://www.yukun.info/blog/2008/02/check-syntax.html#comments</comments>
		<pubDate>Mon, 11 Feb 2008 14:44:09 +0000</pubDate>
		<dc:creator>yukun</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[C language]]></category>
		<category><![CDATA[Stack]]></category>
		<category><![CDATA[String]]></category>

		<guid isPermaLink="false">http://www.yukun.info/trump/20080211/3%e7%a8%ae%e9%a1%9e%e3%81%ae%e6%8b%ac%e5%bc%a7%e3%81%ae%e5%af%be%e5%bf%9c%e3%82%92%e3%83%81%e3%82%a7%e3%83%83%e3%82%af%e3%81%99%e3%82%8bc%e3%83%97%e3%83%ad%e3%82%b0%e3%83%a9%e3%83%a0</guid>
		<description><![CDATA[先日勉強会でこの辺のテーマを取り上げたので、字句解析や構文解析(の一部)とスタックの復習も兼ねて作成(required for 1h+)。 実装のポイント 閉じ括弧の有無の判定は、ファイルの終端が読み終わった後。 開き括 &#8230; <a href="http://www.yukun.info/blog/2008/02/check-syntax.html">Continue reading <span class="meta-nav">&#8594;</span></a><p><a href="http://www.yukun.info/blog/2008/02/check-syntax.html">3種類の括弧の対応をチェックするC言語プログラム</a> is a post from: <a href="http://www.yukun.info">Yukun&#039;s Blog</a></p>
]]></description>
			<content:encoded><![CDATA[<p>先日勉強会でこの辺のテーマを取り上げたので、字句解析や構文解析(の一部)とスタックの復習も兼ねて作成(required for 1h+)。</p>
<h3>実装のポイント</h3>
<ul>
<li>閉じ括弧の有無の判定は、ファイルの終端が読み終わった後。</li>
<li>開き括弧の判定は、閉じ括弧を読み込んだ際に行い、スタックの最上位に対応する開き括弧があるか否かで。</li>
<li>入れ子の(または再帰的な)構造で、どの深さにスレッドがいるか調べるにはスタックを用いる。</li>
</ul>
<h3>ソースコード(C言語) valid_pare.c</h3>
<pre>
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

const int MAXSIZE = 128; // スタックサイズ(静的)
// スタックするデータ構造(Cell)
typedef struct brackets Brackets;
struct brackets {
  int kind; // 括弧の種類
  int line; // 位置：行
  int pos; // 位置：列
};
Brackets stack[128];
int pnt;

Brackets pop(void)
{
  if (pnt &lt; = 0) {
    printf(&quot;error:stack empty.\n&quot;);
    exit(1);
  }
  pnt--;
  return stack[pnt];
}
void push(Brackets b)
{
  if (pnt &gt;= MAXSIZE) {
    printf(&quot;error:stack fullness.\n&quot;);
    exit(1);
  }
  stack[pnt] = b;
  pnt++;
}
// stackが空(1)か否(0)か
int empty(void)
{
  return (pnt == 0) ? 1 : 0;
}
// スタックの最上位の文字種を返す
int peek()
{
  return stack[pnt-1].kind;
}
// 括弧の判別
int kind(int ch)
{
  int code;
  switch (ch) {
  case &#039;(&#039;:
    code = 1;
    break;
  case &#039;)&#039;:
    code = 2;
    break;
  case &#039;{&#039;:
    code = 3;
    break;
  case &#039;}&#039;:
    code = 4;
    break;
  case &#039;[&#039;:
    code = 5;
    break;
  case &#039;]&#039;:
    code = 6;
    break;
  default:
    code = 0; // 括弧以外の文字
    break;
  }
  return code;
}

int main()
{
  int ch;
  FILE *fp;
  char fname[64]; // ファイル名
  int k; // 文字の種類
  int line = 1, pos = 0;
  Brackets kakko, temp;

  pnt = 0; // スタックポインタ(GV)の初期化
  printf(&quot;Filename:&quot;);
  scanf(&quot;%62s&quot;, fname);
  if ((fp = fopen(fname, &quot;r&quot;)) == NULL) {
    printf(&quot;\aCan&#039;t be opened.\n&quot;);
    exit(1);
  }
  //printf(&quot;%d行目\n&quot;, line);
  // ファイルから一文字ずつ読む
  while ((ch = fgetc(fp)) != EOF) {
    //putchar(ch);
    if (ch == &#039;\n&#039;) {
      line++; pos=0;
      //printf(&quot;%d行目\n&quot;, line);
      continue;
    }
    pos++;
    //printf(&quot;%d&quot;, pos);
    k = kind(ch);
    if (k &gt; 0) { // 文字が括弧の場合
      if (k % 2) { // 開き括弧の場合
        kakko.kind = k;
        kakko.line = line;
        kakko.pos  = pos;
        push(kakko);
      } else if (!empty() &amp;&amp; (k == peek()+1)) {
        temp = pop(); // 対応する閉じ括弧があった
      } else {
        printf(&quot;対応する開き括弧がない&quot;);
        printf(&quot;(%d行目の%d文字目)。\n&quot;, line, pos);
      }
    }
  }
  puts(&quot;テキスト終端&quot;);
  fclose(fp);
  if (!empty()) {
    printf(&quot;対応する閉じ括弧がない。\n&quot;);
    while (!empty()) {
      temp = pop();
      printf(&quot;%d行目の%d文字目。\n&quot;, temp.line, temp.pos);
    }
  }
  return 0;
}
</pre>
<h3>使用したText</h3>
<pre>(1+2)
ac)c
((3+6)ge))
(([y)
ij])(k
{5/3}</pre>
<h3>実行結果</h3>
<pre>
D:\parentheses>gcc valid_pare.c
D:\parentheses>a.exe
Filename:pare.txt
対応する開き括弧がない(2行目の3文字目)。
対応する開き括弧がない(3行目の10文字目)。
対応する開き括弧がない(4行目の5文字目)。
テキスト終端
対応する閉じ括弧がない。
5行目の5文字目。
4行目の1文字目。
D:\parentheses>
</pre>
<h3>改良するなら</h3>
<ul>
<li>関数を他のファイルに分けて、main側でインクルードする。</li>
<li>スタック領域を動的に割り当てる。(Brackets *)emalloc(sizeof(Brackets))かな。</li>
<li>スタック配列を伸縮性のある構造・操作関数で実装する。</li>
<li>結果の表示をコンパイラのエラー出力っぽくする。該当箇所に「^」をマーク。</li>
<li>他の言語で実装してみる(OOPを用いて等等)。</li>
<li>字句・構文解析のオープンソースを参考にする。</li>
</ul>
<p>こういった小さなものを作りつつ、OOPのパターンに基づいて拡張性を考慮する今日この頃。</p>
<h4>関連すると思われる記事：</h4>
<ul class="similar-posts">
<li><a href="http://www.yukun.info/blog/2008/01/decimal-to-binary.html" rel="bookmark" title="2008年1月13日">10進数を2進数に変換表示するC言語プログラム</a></li>
<li><a href="http://www.yukun.info/blog/2008/01/ruby-string-index.html" rel="bookmark" title="2008年1月5日">Rubyで文字列から日本語文字をインデックス指定する</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>
<li><a href="http://www.yukun.info/blog/2008/06/python-list2.html" rel="bookmark" title="2008年6月12日">Python: リストの要素の追加と削除、取出し &#8211; append()、extend()、pop()、remove()メソッド</a></li>
<li><a href="http://www.yukun.info/blog/2008/01/x-window-system-color.html" rel="bookmark" title="2008年1月3日">X Window System 上での描画色の変更</a></li>
</ul>
<p><!-- Similar Posts took 7.909 ms --></p>
<p><a href="http://www.yukun.info/blog/2008/02/check-syntax.html">3種類の括弧の対応をチェックするC言語プログラム</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/02/check-syntax.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>10進数を2進数に変換表示するC言語プログラム</title>
		<link>http://www.yukun.info/blog/2008/01/decimal-to-binary.html</link>
		<comments>http://www.yukun.info/blog/2008/01/decimal-to-binary.html#comments</comments>
		<pubDate>Sat, 12 Jan 2008 15:00:00 +0000</pubDate>
		<dc:creator>yukun</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[C language]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[Number]]></category>

		<guid isPermaLink="false">http://www.yukun.info/trump/19700101/10%e9%80%b2%e6%95%b0%e3%82%922%e9%80%b2%e6%95%b0%e3%81%ab%e5%a4%89%e6%8f%9b%e8%a1%a8%e7%a4%ba%e3%81%99%e3%82%8bc%e3%83%97%e3%83%ad%e3%82%b0%e3%83%a9%e3%83%a0</guid>
		<description><![CDATA[ソースコード // filename: dtob.c // convert decimal to binary #include &#60;stdio.h&#62; const int BitSize = sizeof(in &#8230; <a href="http://www.yukun.info/blog/2008/01/decimal-to-binary.html">Continue reading <span class="meta-nav">&#8594;</span></a><p><a href="http://www.yukun.info/blog/2008/01/decimal-to-binary.html">10進数を2進数に変換表示するC言語プログラム</a> is a post from: <a href="http://www.yukun.info">Yukun&#039;s Blog</a></p>
]]></description>
			<content:encoded><![CDATA[<h3>ソースコード</h3>
<pre>
// filename: dtob.c
// convert decimal to binary
#include &lt;stdio.h&gt;

const int BitSize = sizeof(int) * 8; // 整数型のビットサイズを算出
void dtob(int x) {
  int bit = 1, i;
  char c[BitSize];

  for (i = 0; i &lt; BitSize; i++) {
    if (x &amp; bit)
      c[i] = &#039;1&#039;;
    else
      c[i] = &#039;0&#039;;
    bit &lt;&lt;= 1;
  }
  // 計算結果の表示
  printf(&quot;2進数: &quot;);
  for ( i = BitSize - 1; i &gt;= 0; i-- ) {
      putchar(c[i]);
  }
  printf(&quot;\n&quot;);
}

int main()
{
  int x = 0;
  do {
  printf(&quot;10進数を2進数に変換します(0で終了)\n&quot;);
  printf(&quot;xの値: &quot;);
  scanf(&quot;%d&quot;, &amp;x);
  dtob(x);
  } while (x != 0);
  return 0;
}
</pre>
<h3>実行結果</h3>
<pre>[yu@localhost cpp]# gcc dtob.c
[yu@localhost cpp]# ./a.out
10進数を2進数に変換します(0で終了)
xの値: 5
2進数: 00000000000000000000000000000101
10進数を2進数に変換します(0で終了)
xの値: 8
2進数: 00000000000000000000000000001000
10進数を2進数に変換します(0で終了)
xの値: 100
2進数: 00000000000000000000000001100100
10進数を2進数に変換します(0で終了)
xの値: 256
2進数: 00000000000000000000000100000000
10進数を2進数に変換します(0で終了)
xの値: 1984949894
2進数: 01110110010011111110111010000110
10進数を2進数に変換します(0で終了)
xの値: 0
2進数: 00000000000000000000000000000000
[yu@localhost cpp]# </pre>
<p>ビットが0か1の判断するループ順序を逆にして、配列末尾に&#8217;\0&#8242;を代入すれば、計算結果の表示は配列の文字列表示ですみます。そうすると「計算結果の表示」の際にforループを使う必要はないなぁ、と書き終わった今思いました(ぇー)。</p>
<h3>作成の経緯</h3>
<p>以前、拡張ハッシュ法の削除関数を実装している際に、キーをバケットに振り分ける際のアドレス算出の処理部分にデバッグプリントが欲しくて作ったものです。</p>
<h4>関連すると思われる記事：</h4>
<ul class="similar-posts">
<li><a href="http://www.yukun.info/blog/2008/08/python-decimal-to-binary-conversion.html" rel="bookmark" title="2008年8月4日">Python: 10進数整数を2進数文字列に変換する関数</a></li>
<li><a href="http://www.yukun.info/blog/2008/02/check-syntax.html" rel="bookmark" title="2008年2月11日">3種類の括弧の対応をチェックするC言語プログラム</a></li>
<li><a href="http://www.yukun.info/blog/2008/06/opengl-circle.html" rel="bookmark" title="2008年6月20日">OpenGL: ポリゴンで円の描画</a></li>
<li><a href="http://www.yukun.info/blog/2008/01/x-window-system-color.html" rel="bookmark" title="2008年1月3日">X Window System 上での描画色の変更</a></li>
<li><a href="http://www.yukun.info/blog/2008/10/android-integer-to-binary-string.html" rel="bookmark" title="2008年10月29日">Android: 10進数→2進数変換アプリ</a></li>
</ul>
<p><!-- Similar Posts took 7.271 ms --></p>
<p><a href="http://www.yukun.info/blog/2008/01/decimal-to-binary.html">10進数を2進数に変換表示するC言語プログラム</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/01/decimal-to-binary.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>X Window System 上での描画色の変更</title>
		<link>http://www.yukun.info/blog/2008/01/x-window-system-color.html</link>
		<comments>http://www.yukun.info/blog/2008/01/x-window-system-color.html#comments</comments>
		<pubDate>Thu, 03 Jan 2008 13:52:48 +0000</pubDate>
		<dc:creator>yukun</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[C language]]></category>
		<category><![CDATA[Graphics]]></category>
		<category><![CDATA[X11]]></category>

		<guid isPermaLink="false">http://www.yukun.info/trump/20080103/x-window-system-%e4%b8%8a%e3%81%a7%e3%81%ae%e6%8f%8f%e7%94%bb%e8%89%b2%e3%81%ae%e5%a4%89%e6%9b%b4</guid>
		<description><![CDATA[先日X11/Xlib.h、X11/Xutil.hを用いてフラクタルを描画するプログラムを作成していた折、描画する図形を構成する線分の色を変えようと試みました。X Window Systemではあらかじめ定義されている色名 &#8230; <a href="http://www.yukun.info/blog/2008/01/x-window-system-color.html">Continue reading <span class="meta-nav">&#8594;</span></a><p><a href="http://www.yukun.info/blog/2008/01/x-window-system-color.html">X Window System 上での描画色の変更</a> is a post from: <a href="http://www.yukun.info">Yukun&#039;s Blog</a></p>
]]></description>
			<content:encoded><![CDATA[<p>先日X11/Xlib.h、X11/Xutil.hを用いてフラクタルを描画するプログラムを作成していた折、描画する図形を構成する線分の色を変えようと試みました。X Window Systemではあらかじめ定義されている色名があります。<br />
参考サイト：<a href="http://www.nobidome.org/pubdoc/Xrgb.html">X Window System X Window System rgb.txt sample</a><br />
しかし、今回は多くの色を扱うためRGB指定での描画色の変更を行います。まず、以下のような整数型のピクセル値を返す関数MyColorを作成します。</p>
<pre>
#include &lt;x11/Xlib.h&gt;
#include &lt;x11/Xutil.h&gt;

unsigned long MyColor(display, color)
     Display *display;
     char *color;
{
  Colormap cmap;
  XColor c0, c1;
  cmap = DefaultColormap(display, 0);
  XAllocNamedColor(display, cmap, color, &amp;c1, &amp;c0);
  return (c1.pixel);
}
</pre>
<p>引数colorに以下に示す書式に則ったRGB色を表す文字列を代入しピクセル値を得ます。</p>
<p><code>"rgb:<span style="color:#0000FF;">00/00/FF</span>"  (指定した色が青の場合)</code></p>
<p>ここで得られるピクセル値を<span style="color:#6666FF;">XSetForeground</span>関数に代入することでRGB値の指定による描画色の変更を行うことが出来ます。</p>
<p>RGB値指定が可能になることで表現できる色は飛躍的に増えますが、ソースプログラム中にいちいち値を指定した文字列を予め作成しておくのでは、少々非効率な面もあります。<br />
特にフラクタルのような再起関数を用いる場合、繰り返し回数は等比級数的に増す場合もあり、カラフルな図形の表現を行うには別の手法を試みる必要があります。<br />
そこで、上記のRGB値を指定する書式を自動生成する関数のプログラムを以下に示します。</p>
<pre>
#include &lt;stdio.h&gt;
#include &lt;string.h&gt; // for strdup()

// グローバル変数
char *comap[0x1000000]; // RGB形式のカラーマップ
int coindex = 0; // カラーマップ用パラメータ
int colimit = 0; // カラーマップの個数

// RGBカラーマップを生成
// iの可算度合は色のバラツキ度
void cremap()
{
  char str[16];
  int i, j;
  for(i=0, j=0; i&lt; =0xFFFFFF; i+=0x2888, j++) {
    sprintf(str, &quot;rgb:%02X/%02X/%02X&quot;,
      // i / 0xFFFF &amp; 0xFF, i / 0xFF &amp; 0xFF, i &amp; 0xFF); // チョイ非効率
      (i &gt;&gt; 16) &amp; 0xFF, (i &gt;&gt; 8) &amp; 0xFF, i &amp; 0xFF); // bit演算
    comap[j] = strdup(str);
    //puts(comap[i]);
    //printf(&quot;%d\n&quot;, i);
  }
  printf(&quot;%d\n&quot;, j);
  colimit = j; // 生成した色の数
  //exit(0);
}
</pre>
<p>sprintf関数を用いて書式を指定した文字列を生成することが出来ます。for ループのiの増分をi++に変更すれば0xFFFFFF色分のカラーマップを生成できます。ただし、このカラーマップの順序は少々とっぴで、パラメータj順に色を表示すると所所でカラージャンプがあるため、滑らかなグラデーションを生成したい場合はsprintfの引数の指定方法を変える必要があります。</p>
<p>最終的にはソースコード中で以下のように色を変更する一文を加えます。</p>
<p><code>XSetForeground(d,gc, MyColor(d, comap[lim(++coindex)]));</code></p>
<p>これによって生成されたフラクタル画像を下図に示します。左がイニシエータ、右がジェネレータ、中央が生成したフラクタル図形です。</p>
<p><a href="http://www.yukun.info/wp-content/uploads/fractal01s.png"><img src="http://www.yukun.info/wp-content/uploads/fractal01s-e1273384232231.png" alt="からふるフラクタル" title="fractal01s" width="400" height="205" class="size-full wp-image-1558" /></a></p>
<h4>関連すると思われる記事：</h4>
<ul class="similar-posts">
<li><a href="http://www.yukun.info/blog/2008/06/opengl-circle.html" rel="bookmark" title="2008年6月20日">OpenGL: ポリゴンで円の描画</a></li>
<li><a href="http://www.yukun.info/blog/2008/11/actionscript-flash-load-server-image-file.html" rel="bookmark" title="2008年11月21日">ActionScript: 画像ファイルをダウンロードして表示 &#8211; Loaderクラス</a></li>
<li><a href="http://www.yukun.info/blog/2008/01/eclipse-cdt.html" rel="bookmark" title="2008年1月11日">Eclipse+CDTを用いてプロジェクトを作成する際の注意点</a></li>
<li><a href="http://www.yukun.info/blog/2008/02/check-syntax.html" rel="bookmark" title="2008年2月11日">3種類の括弧の対応をチェックするC言語プログラム</a></li>
<li><a href="http://www.yukun.info/blog/2009/02/java-swing-jcomponent-drawing-line.html" rel="bookmark" title="2009年2月21日">Java, Swing: JComponentのGraphicsオブジェクトを用いて直線を描画</a></li>
</ul>
<p><!-- Similar Posts took 7.205 ms --></p>
<p><a href="http://www.yukun.info/blog/2008/01/x-window-system-color.html">X Window System 上での描画色の変更</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/01/x-window-system-color.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C++でMIN以上MAX未満の乱数を生成</title>
		<link>http://www.yukun.info/blog/2008/01/cpp-random.html</link>
		<comments>http://www.yukun.info/blog/2008/01/cpp-random.html#comments</comments>
		<pubDate>Tue, 01 Jan 2008 04:15:40 +0000</pubDate>
		<dc:creator>yukun</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Number]]></category>
		<category><![CDATA[Random]]></category>

		<guid isPermaLink="false">http://www.yukun.info/trump/20080101/c%e3%81%a7min%e4%bb%a5%e4%b8%8amax%e6%9c%aa%e6%ba%80%e3%81%ae%e4%b9%b1%e6%95%b0%e3%82%92%e7%94%9f%e6%88%90</guid>
		<description><![CDATA[ソースコード #include &#60;ctime&#62; // for time() #include &#60;cstdlib&#62; // for srand(), rand() #include &#60;iostr &#8230; <a href="http://www.yukun.info/blog/2008/01/cpp-random.html">Continue reading <span class="meta-nav">&#8594;</span></a><p><a href="http://www.yukun.info/blog/2008/01/cpp-random.html">C++でMIN以上MAX未満の乱数を生成</a> is a post from: <a href="http://www.yukun.info">Yukun&#039;s Blog</a></p>
]]></description>
			<content:encoded><![CDATA[<h3>ソースコード</h3>
<pre>
#include &lt;ctime&gt; // for time()
#include &lt;cstdlib&gt; // for srand(), rand()
#include &lt;iostream&gt;
using namespace std;

#define MIN 10
#define MAX 21

int main()
{
  srand(time(NULL)); // 現在時刻を乱数の種の設定
  int lucky = MIN + rand() % (MAX - MIN); // MIN以上MAX未満の乱数を生成
  cout &lt; &lt; &quot;生成した乱数は&quot; &lt;&lt; lucky &lt;&lt; &quot;です。n&quot;;
  for (int i = 0; i&lt; 100; i++) { // 100個生成
    cout &lt;&lt; MIN + rand() % (MAX - MIN) &lt;&lt; &quot; &quot;;
  }
  return 0;
}
</pre>
<p><span id="more-7"></span></p>
<h3>実行結果</h3>
<p><code><br />
C:cpp> g++ rand01.cpp<br />
C:cpp> a.exe<br />
生成した乱数は19です。<br />
14 13 11 10 18 15 11 14 19 11 11 14 19 17 20 10 10 16 20 18 13 18 17 10 16 19 13 18 14 10 19 17 12 18 20 13 15 14 20 13 10 14 20 15 19 13 11 19 19 13 20 19 15 19 15 13 18 12 18 10 13 14 12 10 16 13 14 20 13 16 11 11 10 12 16 17 13 10 20 11 10 18 12 19 14 18 10 12 12 14 10 15 12 17 19 18 19 17 12 19<br />
C:cpp><br />
</code></p>
<h4>関連すると思われる記事：</h4>
<ul class="similar-posts">
<li><a href="http://www.yukun.info/blog/2008/06/python-random.html" rel="bookmark" title="2008年6月10日">Python: 乱数の生成 &#8211; random()、randint()、uniform()、seed()メソッド</a></li>
<li><a href="http://www.yukun.info/blog/2008/06/python-random2.html" rel="bookmark" title="2008年6月11日">Python: モジュールにテスト関数を定義 &#8211; 重複のない乱数(整数MIN以上MAX以下)の生成</a></li>
<li><a href="http://www.yukun.info/blog/2009/06/excel-vba-random-rnd-cells.html" rel="bookmark" title="2009年6月8日">Excel VBA: 指定した行、列内のテーブルのセルに乱数を格納</a></li>
<li><a href="http://www.yukun.info/blog/2008/09/r-draw-histogram.html" rel="bookmark" title="2008年9月9日">Rで統計: ヒストグラムの描画 &#8211; hist()関数</a></li>
<li><a href="http://www.yukun.info/blog/2008/01/decimal-to-binary.html" rel="bookmark" title="2008年1月13日">10進数を2進数に変換表示するC言語プログラム</a></li>
</ul>
<p><!-- Similar Posts took 6.034 ms --></p>
<p><a href="http://www.yukun.info/blog/2008/01/cpp-random.html">C++でMIN以上MAX未満の乱数を生成</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/01/cpp-random.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

