// signal1.c#include<stdio.h>#include<signal.h>#include<unistd.h>voidsignalHandler(int signo) {if (signo == SIGINT)printf(" received SIGINT\n");}intmain(void) {printf("My pid is %d.\n", getpid());if (signal(SIGINT, signalHandler)== SIG_ERR)printf("\n Can't catch SIGINT\n");// A long long wait so that we can easily issue a signal to this processwhile (1)sleep(1);return0;}
$ gcc -o signal1 signal1.c -Wall
$ ./signal1
My pid is 21231
(ให้กด Ctrl+C เพื่อส่งสัญญาณให้กับโปรแกรม)
^C received SIGINT
^C received SIGINT
^C received SIGINT
^C received SIGINT
^C received SIGINT
^C received SIGINT
(ให้กด Ctrl+Z เพื่อส่งสัญญาณให้กับโปรแกรม)
^Z
[1]+ Stopped ./signal1
หน้าต่าง Terminal 1 ให้ทำการ compile และรันโปรแกรม signal1จะสังเกตเห็นว่าโปรแกรมจะแสดง Process ID (PID) ของตัวเอง เพื่อให้โปรเซสอื่น ๆ สามารถสื่อสารได้
$ gcc -o signal1 signal1.c -Wall
$ ./signal1
My pid is 21231
ให้เปิด terminal ใหม่อีกหน้าต่าง (Terminal 2) แล้วให้พิมพ์คำสั่ง kill เพื่อส่งสัญญาณ SIGINT ไปยัง Process ID หมายเลข 21231 ซึ่งก็คือโปรแกรม signal1 นั่นเอง ดังแสดงข้างล่าง
$ gcc -o signal1 signal1.c -Wall
$ ./signal1
My pid is 21231
received SIGINT <--------- แสดงข้อความเมื่อตรวจจับสัญญาณ SIGINT จาก Terminal 2
ตัวอย่างที่ 2
แสดงตัวอย่างโปรเซสลูกจะวนรอรับ signal ที่จะถูกส่งมาจากผู้ใช้เช่น Ctrl+C เป็นต้น โดยโปรเซสแม่จะรอโปรเซสลูกจนกว่าจะทำงานสิ้นสุด
// signal2.c#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<sys/wait.h>#include<signal.h>voidHandlerChild() {printf("Sigint received by child \n");}voidHandlerParent() {printf("Sigint received by Parent \n");signal(SIGINT, HandlerParent);}int n, statusp;intmain(void) {// signal(SIGINT,HandlerParent); n =fork();if (n ==0) {printf("Child ID %d\n", getpid());signal(SIGINT, HandlerChild);for (;;) { }; } else {printf("Parent ID %d \n", getpid());// signal(SIGINT,HandlerParent);wait(&statusp);// kill(n,SIGKILL);exit(0); }return0;}
$ gcc -o signal2 signal2.c -Wall
$ ./signal2
Parent ID 4564
Child ID 4565
^CSigint received by child
// signal3.c#include<stdio.h>#include<signal.h>#include<unistd.h>int r, count =0, n;voidHL_AlarmSig(int al) {printf(" I am active every 5 sec ");signal(SIGALRM, HL_AlarmSig); r =alarm(5); count++;printf(" .... Now the time is %d sec \n", count *5);}voidHL_AllSig(int s) {printf(" Oh ! I just received signal number %d \n", s);signal(s, HL_AllSig);}intmain(void) {for (n =1; n <=31; n++) {signal(n, HL_AllSig); }signal(SIGALRM, HL_AlarmSig); r =alarm(5);while (count <12) { };printf(" Program Terminate !! ");return0;}
$ gcc -o signal3 signal3.c -Wall
$ ./signal3
^C Oh ! I just received signal number 2
^C Oh ! I just received signal number 2
^C Oh ! I just received signal number 2
I am active every 5 sec .... Now the time is 5 sec
^Z Oh ! I just received signal number 20
^\ Oh ! I just received signal number 3
I am active every 5 sec .... Now the time is 10 sec
I am active every 5 sec .... Now the time is 15 sec
^C Oh ! I just received signal number 2
^C Oh ! I just received signal number 2
^C Oh ! I just received signal number 2
^Z Oh ! I just received signal number 20
^Z Oh ! I just received signal number 20
I am active every 5 sec .... Now the time is 20 sec
I am active every 5 sec .... Now the time is 25 sec
I am active every 5 sec .... Now the time is 30 sec
I am active every 5 sec .... Now the time is 35 sec
I am active every 5 sec .... Now the time is 40 sec
I am active every 5 sec .... Now the time is 45 sec
I am active every 5 sec .... Now the time is 50 sec
I am active every 5 sec .... Now the time is 55 sec
I am active every 5 sec .... Now the time is 60 sec
// signal4.c#include<stdio.h>#include<signal.h>#include<unistd.h>int r, n;voidHL_AlarmSig(int al) {printf(" Every 5 sec I have to tell you this PID \n");printf(" ....... THIS PROCESS ID = %d ....... \n", getpid());signal(SIGALRM, HL_AlarmSig); r =alarm(5);}voidNothing(int s) {signal(s, Nothing);}voidInfiniteLoop(int s) {printf(" No ! I don't care signal number %d \n", s);printf("If you want to stop this process send signal number 9 ONLY!!!\n");signal(s, InfiniteLoop);for (;;) {printf("Loop\n"); }; /* infinite loop */}intmain(void) {for (n =1; n <=31; n++) {signal(n, Nothing); }signal(SIGINT, InfiniteLoop);signal(SIGALRM, HL_AlarmSig);printf(" If you want to go into the infinite loop \n");printf(" .......press ^C within 5 sec...... \n "); r =alarm(5);for (;;) { };printf(" Program Terminate !! \n");return0;}
$ gcc -o signal4 signal4.c -Wall
$ ./signal4
If you want to go into the infinite loop
.......press ^C within 5 sec......
Every 5 sec I have to tell you this PID
....... THIS PROCESS ID = 21538 .......
Every 5 sec I have to tell you this PID
....... THIS PROCESS ID = 21538 .......
(ถ้ากด Ctrl+C โปรแกรมจะเข้าลูปอนันต์)
ตัวอย่างที่ 5
แสดงตัวอย่างโปรแกรม
// signal5.c#include<stdio.h>#include<stdlib.h>#include<signal.h>#include<unistd.h>#include<sys/wait.h>int n, status;voidHL_Child(int s) {printf("**Child**I received signal No. %d .. you can't kill me \n", s);signal(s, HL_Child);}voidHL_Parent(int s) {printf("***Parent*** I received signal number %d \n", s);signal(s, HL_Parent);}voidHL_Parent14(int s) {printf("***Parent*** I received signal No. %d == Alarm Signal \n", s);signal(s, HL_Parent14);}voidHL_Child14(int s) {printf("***Child*** I received signal No %d == Alarm Signal \n", s);signal(s, HL_Child14);}voidHL_Child3(int s) {printf("***Child*** I received signal No %d .. I will exit \n", s);exit(5);}intmain(void) {int i;for (i =1; i <=31; i++)signal(i, HL_Parent); n =fork();if (n ==0) /* Child Process */ {for (i =1; i <=31; i++)signal(i, HL_Child);signal(SIGALRM, HL_Child14);signal(3, HL_Child3);alarm(2);printf("--c-- Child ID = %d \n", getpid());printf("--c-- Child Process goes into the infinite loop \n");printf("--c-- Signal number 3 (^\\) can kill me \n");for (;;) { }; } else /* Parent Process */ {printf("--p-- Parent ID = %d \n", getpid());signal(SIGALRM, HL_Parent14); /* alarm(2); */printf("--p-- I am waiting for child exit or any signal \n");wait(&status);printf("--p-- Wait completed !! and I am waiting again ...\n");wait(&status);printf("--p-- Wait completed !! ...exit status = %d\n", status >>8);printf("--p-- I am pausing for check signal from child exit ... \n");pause();wait(&status);printf("--p-- Wait completed !! ...exit status = %d \n", status >>8);printf("--p-- I will execute newprog now !! \n");for (i =1; i <=31; i++)signal(i, SIG_IGN);signal(3, SIG_DFL);signal(2, HL_Parent); i =execl("newprog","newprog",0);printf("--p-- Parent Process terminated !!\n");exit(0); }return0;}
$ gcc -o signal5 signal5.c -Wall
$ ./signal5
--p-- Parent ID = 22119
--p-- I am waiting for child exit or any signal
--c-- Child ID = 22120
--c-- Child Process goes into the infinite loop
--c-- Signal number 3 (^\) can kill me
(กด Ctrl+C เพื่อส่งสัญญาณให้ child process)
^C***Parent*** I received signal number 2
**Child**I received signal No. 2 .. you can't kill me
(กด Ctrl+C เพื่อส่งสัญญาณให้ child process)
^C***Parent*** I received signal number 2
**Child**I received signal No. 2 .. you can't kill me
***Child*** I received signal No 14 == Alarm Signal
(กด Ctrl+Z เพื่อส่งสัญญาณให้ child process)
^Z**Child**I received signal No. 18 .. you can't kill me
***Parent*** I received signal number 18
(ถ้ากด Ctrl+\ เพื่อส่งสัญญาณให้ child process เพื่อเรียกฟังก์ชัน HL_Child3() )
^\***Parent*** I received signal number 3
***Child*** I received signal No 3 .. I will exit
***Parent*** I received signal number 20
--p-- Wait completed !! and I am waiting again ...
--p-- Wait completed !! ...exit status = 5
--p-- I am pausing for check signal from child exit ...
(กด Ctrl+C เพื่อสั่งหยุดโปรแกรม)
^C***Parent*** I received signal number 2
--p-- Wait completed !! ...exit status = 5
--p-- I will execute newprog now !!
--p-- Parent Process terminated !!
/* * signal6.c * * The parent process pulls a child exit status whenever the OS notifies * a child status change. * * Created by Mij <mij@bitchx.it> on 04/01/05. * Original source file available at http://mij.oltrelinux.com/devel/unixprg/ * *//* for printf() and fgetc() */#include<stdio.h>/* for fork() */#include<sys/types.h>#include<unistd.h>/* for srandom() and random() */#include<stdlib.h>/* for time() [seeding srandom()] */#include<time.h>/* for waitpid() */#include<sys/wait.h>/* for signal(), kill() and raise() */#include<signal.h>/* how many childs to raise */#defineNUM_PROCS5/* handler prototype for SIGCHLD */voidchild_handler(int);intmain(int argc,char*argv[]) {int i, exit_status; /* execute child_handler() when receiving a signal of type SIGCHLD */signal(SIGCHLD,&child_handler); /* initialize the random num generator */srandom(time(NULL));printf("Try to issue a \'ps\' while the process is running...\n"); /* produce NUM_PROCS childs */for (i =0; i < NUM_PROCS; i++) {if (!fork()) { /* child */ /* choosing a random exit status between 0 and 99 */ exit_status = (int) (random()%100);printf(" -> New child %d, will exit with %d.\n", (int) getpid(), exit_status); /* try to skip signals overlapping */sleep((unsignedint) (random() %3)); /* choosing a value to exit between 0 and 99 */exit(exit_status); } /* father */sleep((unsignedint) (random() %2)); } /* checkpoint */printf("parent: done with fork()ing.\n"); /* why this is not equivalent to sleep(20) here? */for (i =0; i <10; i++) {sleep(1); } /* all the child processes should be done now */printf("I did not purge all the childs. Timeout; exiting.\n"); /* terminate myself => exit */kill(getpid(),15); /* this won't be actually executed */return0;}/* handler definition for SIGCHLD */voidchild_handler(int sig_type) {int child_status;pid_t child;staticint call_num =0; /* getting the child's exit status */ child =waitpid(0,&child_status,0);printf("<- Child %d exited with status %d.\n", child, WEXITSTATUS(child_status)); /* did we get all the childs? */if (++call_num >= NUM_PROCS) {printf("I got all the childs this time. Going to exit.\n");exit(0); }return;}
$ gcc -o signal6 signal6.c -Wall
$ ./signal6
Try to issue a 'ps' while the process is running...
-> New child 12274, will exit with 68.
-> New child 12275, will exit with 57.
-> New child 12276, will exit with 96.
parent: done with fork()ing.
-> New child 12277, will exit with 18.
-> New child 12278, will exit with 72.
<- Child 12275 exited with status 57.
<- Child 12274 exited with status 68.
<- Child 12277 exited with status 18.
<- Child 12276 exited with status 96.
<- Child 12278 exited with status 72.
I got all the childs this time. Going to exit.
Assoc. Prof. Wiroon Sriborrirux, Founder of Advance Innovation Center (AIC) and Bangsaen Design House (BDH), Electrical Engineering Department, Faculty of Engineering, Burapha University