// signal1.c
#include<stdio.h>
#include<signal.h>
#include<unistd.h>
void signalHandler(int signo) {
if (signo == SIGINT)
printf(" received SIGINT\n");
}
int main(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 process
while (1)
sleep(1);
return 0;
}
$ 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 นั่นเอง ดังแสดงข้างล่าง
// signal3.c
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
int r, count = 0, n;
void HL_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);
}
void HL_AllSig(int s) {
printf(" Oh ! I just received signal number %d \n", s);
signal(s, HL_AllSig);
}
int main(void) {
for (n = 1; n <= 31; n++) {
signal(n, HL_AllSig);
}
signal(SIGALRM, HL_AlarmSig);
r = alarm(5);
while (count < 12) {
};
printf(" Program Terminate !! ");
return 0;
}
$ 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;
void HL_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);
}
void Nothing(int s) {
signal(s, Nothing);
}
void InfiniteLoop(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 */
}
int main(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");
return 0;
}
$ 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;
void HL_Child(int s) {
printf("**Child**I received signal No. %d .. you can't kill me \n", s);
signal(s, HL_Child);
}
void HL_Parent(int s) {
printf("***Parent*** I received signal number %d \n", s);
signal(s, HL_Parent);
}
void HL_Parent14(int s) {
printf("***Parent*** I received signal No. %d == Alarm Signal \n", s);
signal(s, HL_Parent14);
}
void HL_Child14(int s) {
printf("***Child*** I received signal No %d == Alarm Signal \n", s);
signal(s, HL_Child14);
}
void HL_Child3(int s) {
printf("***Child*** I received signal No %d .. I will exit \n", s);
exit(5);
}
int main(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);
}
return 0;
}
$ 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 */
#define NUM_PROCS 5
/* handler prototype for SIGCHLD */
void child_handler(int);
int main(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((unsigned int) (random() % 3));
/* choosing a value to exit between 0 and 99 */
exit(exit_status);
}
/* father */
sleep((unsigned int) (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 */
return 0;
}
/* handler definition for SIGCHLD */
void child_handler(int sig_type) {
int child_status;
pid_t child;
static int 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.