「pthread スレッドから値を返す方法」の版間の差分
提供: C言語入門
(ページの作成:「pthread のスレッドからメインスレッドに値を返す方法は、いくつかあります。引数から返す、確保したメモリのポインタをre...」) |
(→ソースコード pthread_join1.c) |
||
行14: | 行14: | ||
#include <stdlib.h> | #include <stdlib.h> | ||
#include <err.h> | #include <err.h> | ||
+ | #include <string.h> | ||
#include <pthread.h> | #include <pthread.h> | ||
#include <unistd.h> | #include <unistd.h> | ||
行28: | 行29: | ||
if (ret1 != 0) { | if (ret1 != 0) { | ||
− | err(EXIT_FAILURE, "can not create thread 1"); | + | err(EXIT_FAILURE, "can not create thread 1: %s", strerror(ret1) ); |
} | } | ||
if (ret2 != 0) { | if (ret2 != 0) { | ||
− | err(EXIT_FAILURE, "can not create thread 2"); | + | err(EXIT_FAILURE, "can not create thread 2: %s", strerror(ret2) ); |
} | } | ||
行37: | 行38: | ||
ret1 = pthread_join(thread1,&status1); | ret1 = pthread_join(thread1,&status1); | ||
if (ret1 != 0) { | if (ret1 != 0) { | ||
− | + | errc(EXIT_FAILURE, ret1, "can not join thread 1"); | |
} | } | ||
ret2 = pthread_join(thread2,&status2); | ret2 = pthread_join(thread2,&status2); | ||
if (ret2 != 0) { | if (ret2 != 0) { | ||
− | + | errc(EXIT_FAILURE, ret2, "can not join thread 2"); | |
} | } | ||
行51: | 行52: | ||
free (status2); | free (status2); | ||
− | + | exit(EXIT_SUCCESS); | |
} | } | ||
行81: | 行82: | ||
return p; | return p; | ||
} | } | ||
+ | ~ | ||
+ | |||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | |||
=== コンパイル === | === コンパイル === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> |
2014年5月11日 (日) 16:08時点における最新版
pthread のスレッドからメインスレッドに値を返す方法は、いくつかあります。引数から返す、確保したメモリのポインタをreturnもしくはpthread_exitで返す、などです。
概要
スレッドからreturn、もしくは、pthread_exit()で渡したポインタをpthread_joinで参照できます。 スレッド内の自動変数のポインタを返しても、動いてるように見えるかもしれませんが、おそらく、危険なコードでしょう。 ここでの例は、int型のメモリを確保して、値を1つだけ返していますが、複数のデータを返却したい場合には、返したいデータをひとまとめにした構造体をmallocして、データを詰め込んで返すと良いでしょう。
pthread_exitで値を返す例
ここでは、あえて、returnとpthread_exitの両方を使用しています。
ソースコード pthread_join1.c
#include <stdio.h> #include <stdlib.h> #include <err.h> #include <string.h> #include <pthread.h> #include <unistd.h> void* f1(); void* f2(); int main(int argc, char *argv[]) { pthread_t thread1, thread2; int ret1,ret2; ret1 = pthread_create(&thread1,NULL,(void *)f1,NULL); ret2 = pthread_create(&thread2,NULL,(void *)f2,NULL); if (ret1 != 0) { err(EXIT_FAILURE, "can not create thread 1: %s", strerror(ret1) ); } if (ret2 != 0) { err(EXIT_FAILURE, "can not create thread 2: %s", strerror(ret2) ); } void *status1, *status2; ret1 = pthread_join(thread1,&status1); if (ret1 != 0) { errc(EXIT_FAILURE, ret1, "can not join thread 1"); } ret2 = pthread_join(thread2,&status2); if (ret2 != 0) { errc(EXIT_FAILURE, ret2, "can not join thread 2"); } printf("status1 = %p, %d\n", status1, * (int*) status1); printf("status2 = %p, %d\n", status2, * (int*) status2); free (status1); free (status2); exit(EXIT_SUCCESS); } void* Malloc(size_t size) { void *p = malloc(size); if (NULL == p) { err(EXIT_FAILURE, "malloc error: %lu", size); } return p; } void* f1() { int status = 123; void *p = Malloc(sizeof(int)); printf("%s: %p\n", __func__, p); *(int*)(p) = 123; pthread_exit(p); } void* f2() { void *p = Malloc(sizeof(int)); printf("%s: %p\n", __func__, p); *(int*)(p) = 456; return p; } ~
コンパイル
cc -lpthread pthread_join1.c -o pthread_join1
実行例
% ./pthread_join1 f2: 0x80180e058 f1: 0x801c0e058 status1 = 0x801c0e058, 123 status2 = 0x80180e058, 456
このように、データをメインスレッド(main)に返すことができました。
スレッドの引数で返す方法
pthread スレッドに値を渡す方法をご参照ください。