● threadとfork,execの注意点
UNIX上でのC++ソフトウェア設計の定石 (3)
https://yupo5656.hatenadiary.org/entry/20040715/p1
fork()してからexec()するまでの間は、fork-unsafeな関数しか呼んではいけない。ハマりやすいのはsetenv()系とmalloc()系、execvp()とかsprintf()とか要注意。
とはいえ、glibcだと%dではmalloc()しないから意外と大丈夫だったりと、この手のは確認するだけでめんどい。
● vfork()も楽じゃない
じゃvfork()にしとくか、と思っても実はそう簡単にはいかない話。
linux - 大量のメモリを使用するプログラムからコマンドを実行する方法 - スタック・オーバーフロー
https://ja.stackoverflow.com/questions/9920/
の、特にkosakiさんのコメント部分、
2014-09-06 (Sat) - 天泣記
http://www.a-k-r.org/d/2014-09.html#a2014_09_06
● 環境変数
/proc/[PID]/environは、プロセスの起動時の環境変数しか取れない。
/proc/pid/environでは任意のプロセスの全ての環境変数を取得できない?
https://stupiddog.jp/note/archives/1073
じゃどうするのかというと、環境変数というものがkernelがfork()時に親から子にごニョる機能しか提供しないため、プロセスが自分で設定した環境変数は外部からは観測不可能。
man environをちゃんと読んで理解しとけと。
プロセス内からは、グローバル変数environを介してアクセスする。
extern char **environ static void print_env_all(){ int i; char **p = environ; for( i=0; p[i]; i++) { printf("%s\n", p[i]); } }
● シグナルハンドラの確認方法
current->sighandが、シグナルハンドラの情報が乗ってるstruct sighand_struct型の変数。
何も気にせずプログラムを組むとこんなのが登録されてる。
- sigcancel_handler() SIGCANCEL > SIGCANCEL(pthread_cancel()の内部実装)
- sighandler_setxid() SIGSETXID > よく理解できてないけど、setuid(), setgid()に必要らしい。
● pthread_cancel()時の後処理
終了のさせ方
- pthread_cancel()
- pthread_kill()
- pthread_exit()
- main()をreturn
- exit()
- quick_exit()
- _exit()
クリーンナップの登録
- pthread_cleanup_push()
- pthread_key_create()
- atexit()
- at_quick_exit()
起動時コンストラクタと優先度
- static initializer
- __attribute__((init_priority(1)))
- __attribute__((constructor(65535)))
- __attribute__((destructor(65535)))と。
exit時になにかの処理をすることを期待するのはやはり筋が悪すぎる。
(下記のサンプルプログラムはあとで改良する)
#include#include int main(){ int ret; printf("do\n"); ret = pthread_cancel(pthread_self()); if (ret){ perror("pthread_cancel"); } printf("done1\n"); printf("done2\n"); printf("done3\n"); return 0; }