2012年9月1日土曜日

マルチスレッドとは・・・

このエントリーをはてなブックマークに追加
マルチスレッドプログラムについて経験値がいくらかたまったので、一度自分の知見をまとめてみようと思います。自分の知識の整理を目的としたいと思います。

スレッドとは

端的に言うと、スレッドとは、プログラムを実行する主体の最小単位です。ここで言っている主体とは、例えば、a.outという実行ファイルを実行する"そのもの"を指します。プログラムを実行するスレッドが1つであればそれをシングルスレッドプログラムと呼び、プログラムを実行するスレッドが複数であればそれをマルチスレッドプログラムと呼びます。シングルスレッドプログラムはa.outを逐次実行し、マルチスレッドプログラムはa.outを並列・並行実行します。
次にリソースの観点では、スレッドはプログラムカウンタを始めとしたレジスタ群とスタックを個別に持ちます。スレッドは、プログラムを実行する主体の最小単位であるため、それぞれに個別のプログラムカウンタとスタックを持つ必要があります。一方で、命令コードと静的データ、ヒープは、スレッド間で共有されます。これら命令コード、静的データ、ヒープを所有する主体となるのが、プロセスです。
スレッドは、必ず1つのプロセスに属します。また、1つのスレッドが2つ以上のプロセスに属することはありません。プロセスというのは、実行される実行ファイルごとのメモリ上の区切りのようなものです。プロセスごとに、命令コード、静的データ、ヒープ、スタックをメモリ上に持ちます。実行ファイルa.outを2つ同時に実行すれば、2つのプロセスがコンピュータ上に同時に存在するということになります。もちろんこのとき、それぞれのプロセスにスレッドが存在します。

シングルスレッドプログラムとマルチスレッドプログラム

シングルスレッドプログラムとマルチスレッドプログラムの実装の違いを、簡単に見てみます。マルチスレッドプログラムで用いるスレッドライブラリは、openMPとpthreadを使いました。
以下、printfを10回実行するプログラムです。環境によっては、マルチスレッドプログラムのhelloがプリントされる順番が入れ替わったりするかと思います。

singleThread.c
#include <stdio.h>

int main(void)
{
 int i;
 
 for(i = 0; i < 10; i++)
 {
  printf("hello%d\n", i);
 }
 
 return 0;
}

multiThread_openMP.c
#include <stdio.h>
#include <omp.h>

int main(void)
{
 int i;
 
 #pragma omp parallel for
 for(i = 0; i < 10; i++)
 {
  printf("hello%d\n", i);
 }
 
 return 0;
}

multiThread_pthread.c
#include <stdio.h>
#include <pthread.h>

#define NUMOF_THREADS 10

void* printHello(void* arg)
{
 printf("hello%d\n", *(int*)arg);
}

int main(void)
{
 int i;
 pthread_t threads[NUMOF_THREADS];
 int threadArg[NUMOF_THREADS];
 
 for(i = 0; i < NUMOF_THREADS; i++)
 {
  threadArg[i] = i;
  pthread_create(&threads[i], NULL, printHello, (void*)&threadArg[i]);
 }
 
 for(i = 0; i < NUMOF_THREADS; i++)
 {
  pthread_join(threads[i], NULL);
 }
 
 return 0;
}


singleThread.cは、単にprintfをfor文で回しているだけなので、特に問題ないと思います。
multiThread_openMP.cは、singleThread.cとほぼ同じです。異なるのは、openMPのヘッダをインクルードしていることと、for文の前に#pragma omp paralle forの1行があることだけです。たったこれだけで、for文のなかのprintfが並列・並行実行されます。
multiThread_pthread.cは、openMPのものと同じ並列・並行実行であるのに対して、コード量が多くなっています。これは、pthreadでは、スレッドの作成と、終了待ちを関数呼び出しで明示的に行う必要があるためです。openMPの方では、ほぼスレッドなど意識せずただfor文を並列に実行する、とプログラムしているだけでした。
上記の例を一見すると、openMPの方が簡単にマルチスレッドプログラムを作ることができます。しかし、for文の並列化はopenMPが得意とするところなので、openMPの方がコード量を少なく記述できているだけです。
世にいくつかもあるスレッドライブラリですが、それぞれに得意なところ、不得意なところがあります。得意なところは、比較的コード量が少なくなり、不得意なところはコード量が多くなるのが一般的かと思います。また、各スレッドの同期等の細かな動作を細かく制御できるスレッドライブラリは、細かく制御できる分、コード量が多めになる傾向があります。pthreadは比較的何でもできるスレッドライブラリなので、並列化のためのコード量が多めになりがちです。

まとめ

スレッドの概念、スレッドとプロセスの関係を説明し、マルチスレッドプログラムの例を見ました。スレッドライブラリはいくつもあり、それぞれに得意・不得意なところを持っていることを述べました。マルチスレッドプログラムに関して、説明しなかったしなかったことは、なぜマルチスレッドにするのか?、何をマルチスレッド化するのか?、どのようにマルチスレッド化するのか?といったことになります。こういったことは、マルチスレッドに関する本が参考になります。また、現実に使われているマルチスレッドプログラムを探しだして読むことも参考になります。


2012年8月26日日曜日

気になる色を調べたい『色彩ヘルパー』

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

目の前の素敵な色や、写真に含まれている色を調べたいとき、『色彩ヘルパー(Coler Helper)』が便利です。『色彩ヘルパー』は、iPhoneやiPadで利用できるアプリで、カメラで映した映像や、端末内に保存されている画像に含まれている色を識別してくれます。


カメラで撮影中の映像に含まれるカラーをリアルタイムで表示します。iOS端末内に保存されている写真のカラーも、読み込んで表示します。



色見本では、色のサンプルが一覧になっていて、色を参照するのにとても便利です。配色に悩んだ時、このアプリがあればとても心強いと思います。 

App Store:色彩ヘルパー

2012年8月18日土曜日

CGRectContainsPointで特定の範囲がタッチされたかどうかを判別する

このエントリーをはてなブックマークに追加
CGRectContainsPointは、指定した領域に指定した位置が含まれるかどうかを判別するメソッドです。これを利用して、指定した範囲がタッチされたかどうかを判別するサンプルを書きました。


プログラム
タッチした時に呼ばれるtouchesBeganメソッドで、CGRectContainsPointを利用した分岐処理を記述しました。CGRectContainsPointの第一引数は領域、第二引数は位置を指定します。

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    CGRect targetRect = CGRectMake(0, 0, 44, 44);
    CGPoint location = [[touches anyObject] locationInView:self];
    if (CGRectContainsPoint(targetRect, location)) {
        NSLog(@"touched in targetRect");
    }
}


xやyといった位置や、widthやheightといった幅や高さで判別するような記述を行わなくて済むので、これで記述量が少なくなりそうです。

関連:iPhoneでのタッチやタップをtouchesBeganで検知する

2012年8月8日水曜日

Windows XPにスナップに似た機能を搭載する『WinSplit Revolution』

このエントリーをはてなブックマークに追加
Windows 7のスナップ機能はドラッグ操作で画面を整理するのに便利な機能です。慣れると手放せなくなる機能ですが、Windows XPにはその機能がありません。ただ、画面を整理するという点で、スナップに似た機能を実現するソフトウェアがありました。『WinSplit Revolution』といいます。


インストールすると、タスクトレイにアプリが表示されます。アイコンをクリックすると上図のような画面が現れます。例えば左上にウィンドウを合わせたい時は、対象のウィンドウを選択して左上矢印のボタンをクリックします。

専ら便利なのは画面整理のショートカットを作成できる点です。例えば、[Win] + [Ctrl] + 上矢印キーでウィンドウを上部に合わせるといったことができます。ショートカットの設定は[Hotkey settings]からできます。

たくさん起動したTera Termを見やすく並べたり、WordやExcel等の内容比較をやりやすくするのに便利なツールです。

2012年8月7日火曜日

MacBookにスナップ機能を搭載する『BetterTouchTool』

このエントリーをはてなブックマークに追加
スナップ機能とは、Windows 7に搭載されている機能で、ウィンドウを画面の端にドラッグすると画面のサイズを自動で調整してくれる機能です。Mac OS Xにはその機能は無いのですが、『BetterTouchTool』を使うとそんなスナップ機能が実現できます。

DL:http://blog.boastr.net/