[解決済み] setpgid() による子プロセスのグループ化
2022-02-14 14:45:37
質問
全体がわからないんです。
私のプロセスツリー
0
/ \
1 2
/ \
5 3
/
4
プロセスグループ(3,4,5)を作り、このグループに例えば2からのシグナルを送りたい。
この方法でやってみました。
setpgid(pid3, pid3);
setpgid(pid4, pid3);
setpgid(pid5, pid3);
...
kill(-pid3, SIGUSR1);
をどこに配置すればいいのでしょうか?
setpgid()
ブロックを作成します。3、0、その他全ての処理に配置してみましたが
setpgid()
は、"No such process" または "Operation not permitted" のいずれかを返します。
pidはファイルに保存されているので
setpgid()
どのように解決するのですか?
あるプロセスでは、プロセスグループIDを のみ、またはその子である . さらに、子プロセスがexec関数のいずれかを呼び出した後は、その子プロセスのプロセスグループIDを変更することができません。 --APUE
私見ですが
1.祖父母はそのgradechildでsetgpid()を使用することはできません。
setpgid(pid3, pid3); setpgid(pid4, pid3); setpgid(pid5, pid3);
2.setgpid()で変更できるのは、自分とその子供のpgidのみです。pid 3とpid 5は親子ではないので、pid 3にsetpgid(pid5, pid3)とは書けないのです。
だから、setgpid(誰かのpid, pgid)単体で使った方がいいんだよ。
しかし、あるプロセスが他のプロセスのpidを知るにはどうしたらいいのでしょうか?その方法として、共有メモリがあります。
以下は、私が書いた、プロセスの同期を考慮しないラフな、しかし少し複雑な実装です。
#include "stdlib.h"
#include "stdio.h"
#include "errno.h"
#include "unistd.h"
#include "string.h"
#include "sys/stat.h"
#include "sys/types.h"
#include "sys/ipc.h"
#include "sys/shm.h"
#include "signal.h"
#define PERM S_IRUSR|S_IWUSR
void sig_usr3(int);
void sig_usr4(int);
void sig_usr5(int);
int main() {
size_t msize;
key_t shmid;
pid_t *pid;
msize = 6 * sizeof(pid_t);
if( (shmid = shmget(IPC_PRIVATE, msize , PERM)) == -1 ) {
fprintf(stderr, "Share Memory Error:%s\n\a", strerror(errno));
exit(1);
}
pid = shmat(shmid, 0, 0);
memset(pid,0,msize);
pid[0] = getpid();
//process 0
if(fork() == 0) {
//process 1
pid = shmat(shmid, 0, 0);
pid[1] = getpid();
if(fork() == 0) {
//process 5
pid = shmat(shmid, 0, 0);
pid[5] = getpid();
while(pid[3]==0)
sleep(1);
if((setpgid(pid[5],pid[3]))==-1)
printf("pid5 setpgid error.\n");
signal(SIGUSR1,sig_usr5);
for(;;)
pause();
}
for(;;)
pause();
exit(0);
}
if(fork() == 0) {
//process 2
pid = shmat(shmid, 0, 0);
pid[2] = getpid();
if(fork() == 0) {
//process 3
pid = shmat(shmid, 0, 0);
pid[3] = getpid();
if((setpgid(pid[3],pid[3]))==-1)
printf("pid3 setpgid error.\n");
if(fork() == 0) {
//process 4
pid = shmat(shmid, 0, 0);
pid[4] = getpid();
if((setpgid(pid[4],pid[3]))==-1)
printf("pid4 setpgid error.\n");
signal(SIGUSR1,sig_usr4);
for(;;)
pause();
}
else {
signal(SIGUSR1,sig_usr3);
for(;;)
pause();
}
for(;;)
sleep(100);
}
if(getpid()==pid[0]) {
int i,flag;
while(!(pid[0]&&pid[1]&&pid[2]&&pid[3]&&pid[4]&&pid[5]))
//wait for all process folking.
sleep(1);
for(i=0;i<6;i++)
printf("process %d,pid:%d\n",i,pid[i]);
kill(-pid[3],SIGUSR1);
}
}
void sig_usr3(int signo) {
if(signo == SIGUSR1)
printf("recieved sigal in process 3\npid is %d\n\n",getpid());
exit(0);
}
void sig_usr4(int signo) {
if(signo == SIGUSR1)
printf("recieved sigal in process 4\npid is %d\n\n",getpid());
exit(0);
}
void sig_usr5(int signo) {
if(signo == SIGUSR1)
printf("recieved sigal in process 5\npid is %d\n\n",getpid());
exit(0);
}
を出力します。
process 0,pid:31361
process 1,pid:31362
process 2,pid:31363
process 3,pid:31364
process 4,pid:31366
process 5,pid:31365
recieved sigal in process 3
pid is 31364
recieved sigal in process 5
pid is 31365
recieved sigal in process 4
pid is 31366
関連
-
[解決済み】Cコンパイルエラー。"変数サイズのオブジェクトが初期化されていない可能性がある"
-
[解決済み】C言語におけるファイルスコープでの可変長配列の変更
-
[解決済み】 strcpyとstrdupの比較
-
[解決済み】警告。この関数ではXが初期化されていない状態で使用される可能性があります。
-
[解決済み】スレッド1:EXC_BAD_ACCESS(コード=1、アドレス=0x0)標準Cメモリ問題
-
[解決済み】エラー。非スカラー型への変換を要求された
-
[解決済み] C: エラー: ';'トークンの前に ')' があると予想される
-
[解決済み】execvp: バッドアドレスエラー
-
[解決済み] 配列の場合、なぜ a[5] == 5[a] になるのでしょうか?
-
[解決済み] エクスポートあり/なしの変数の定義
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】変数の警告が設定されているが使用されていない
-
[解決済み】警告:互換性のないポインタ型からの代入
-
[解決済み】ポインタへの代入時に互換性のないポインタ型からの初期化警告が発生した
-
[解決済み】デバッガgdbの使用時に不明な終了シグナルが発生する。
-
[解決済み】 strcpyとstrdupの比較
-
[解決済み] char pointers: 'char*' から 'char' への無効な変換?
-
[解決済み] テスト
-
[解決済み] '{'トークンの前に期待される式
-
[解決済み】エラー:呼び出されたオブジェクトは、関数または関数ポインタではない
-
[解決済み】C言語でpow( )への未定義参照、math.hを含むにもかかわらず【重複】。