だらだら書くよ
初めてのコード
#include <pthread.h> void* f(void* p) { puts("hello"); sleep(1); puts("hello"); sleep(1); puts("hello"); } int main(int argc, char** argv) { pthread_t thread; pthread_create(&thread, NULL, f, (void*)NULL); pthread_join(thread, NULL); }
$ gcc p.c -lpthread && ./a.out hello hello hello $
おおお。スレッドスレッド
みゅーてっくつ
#include <pthread.h> // みゅーてっくつ pthread_mutex_t m; void* f(void* p) { int i; for (i = 0; i < 10; i ++) { // こっから pthread_mutex_lock(&m); putchar('h'); sleep(0); putchar('e'); sleep(0); putchar('l'); sleep(0); putchar('l'); sleep(0); putchar('o'); sleep(0); putchar('\n'); pthread_mutex_unlock(&m); // ここまで // クリティカルセクション } } int main(int argc, char** argv) { // みゅーてっくつの // 本当は返り値を判定すべき // 返り値が 0 だと成功 pthread_mutex_init(&m, NULL); // ← この NULLが気になって死ぬ pthread_t thread0; pthread_t thread1; pthread_create(&thread0, NULL, f, (void*)NULL); pthread_create(&thread1, NULL, f, (void*)NULL); pthread_join(thread0, NULL); pthread_join(thread1, NULL); // 後始末 pthread_mutex_destroy(&m); }
実行!
$ gcc p.c -lpthread && ./a.out hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello $
うひょー!
ロックしてる部分をコメントアウトしてみる
void* f(void* p) { int i; for (i = 0; i < 10; i ++) { // pthread_mutex_lock(&m); putchar('h'); sleep(0); putchar('e'); sleep(0); putchar('l'); sleep(0); putchar('l'); sleep(0); putchar('o'); sleep(0); putchar('\n'); // pthread_mutex_unlock(&m); } }
$ gcc p.c -lpthread && ./a.out hheelllloo h heelllloo h heelllloo h heelllloo h heelllloo h heelllloo h heelllloo h heelllloo h heelllloo h heelllloo $
わー!バラバラ!
みゅーてっくつ!
てっくつ!てっくつ!
pthead_mutex_init の第二引数
気になる
そんなときは、
$ man pthread
pthread_mutex_init のところには
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) Initialize a mutex with specified attributes.
って書いてあった
よくわからん><
ググるカスσ(・∀・;)
こんなページみっけた
http://developer.apple.com/documentation/Darwin/Reference/ManPages/man3/pthread_mutexattr_settype.3.html
pthread_mutex_init (&m, NULL);
は
pthread_mutexattr_t mattr; pthread_mutexattr_init(&mattr); pthread_mutex_init(&m, &mattr); pthread_mutexattr_destroy(&mattr);
と同じってことね。
で mattr の値を変えるときは、
pthread_mutexattr_setprioceiling
pthread_mutexattr_setprotocol
pthread_mutexattr_settype
を使うのか。
じゃあ再帰ロックちゅーのを試してみる
さっきのループを強引に再帰に
#include <pthread.h> // みゅーてっくつ pthread_mutex_t m; char* s = "hello\n"; void* f(void* p) { int count = (int)p; if (count == 10) return; pthread_mutex_lock(&m); putchar('h'); sleep(0); putchar('e'); sleep(0); putchar('l'); sleep(0); putchar('l'); sleep(0); putchar('o'); sleep(0); putchar('\n'); // わざわざココで再帰(ロックの中でロック) f((void*)(count + 1)); pthread_mutex_unlock(&m); } int main(int argc, char** argv) { pthread_mutexattr_t mattr; pthread_mutexattr_init(&mattr); // ここで、再帰ロック可能ねって言ってる pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&m, &mattr); pthread_mutexattr_destroy(&mattr); pthread_t thread0; pthread_t thread1; pthread_create(&thread0, NULL, f, (void*)0); pthread_create(&thread1, NULL, f, (void*)0); pthread_join(thread0, NULL); pthread_join(thread1, NULL); pthread_mutex_destroy(&m); }
じゃあ、実行!
$ gcc p.c -lpthread && ./a.out hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello $
わー!
ロックの中でロックできてる
ろっけんろー
じゃあ、以下の行をコメントアウトしてみる
//pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE);
$ gcc p.c -lpthread && ./a.out hello (固まる)
おおおお。
ちゃんと動かなかった!
次は、せまふぉ
(ここで、はてながメンテになって書けなかった><)