1. Trang chủ
  2. » Công Nghệ Thông Tin

Thực hành hệ điều hành 2 tín hiệu và truyền thông giữa các quy trình

11 168 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 11
Dung lượng 68 KB

Nội dung

Tirgul Signals and communication between processes What Are Signals? Signals, to be short, are various notifications sent to a process in order to notify it of various "important" events By their nature, they interrupt whatever the process is doing at this minute, and force it to handle them immediately Each signal has an integer number that represents it (1, and so on), as well as a symbolic name that is usually defined in the file /usr/include/signal.h or one of the files included by it directly or indirectly (HUP, INT and so on Use the command 'kill -l' to see a list of signals supported by your system) Each signal may have a signal handler, which is a function that gets called when the process receives that signal The function is called in "asynchronous mode", meaning that no where in your program you have code that calls this function directly Instead, when the signal is sent to the process, the operating system stops the execution of the process, and "forces" it to call the signal handler function When that signal handler function returns, the process continues execution from wherever it happened to be before the signal was received, as if this interruption never occurred What Are Signals Used For? Signals are usually used by the operating system to notify processes that some event occurred, without these processes needing to poll for the event Sending Signals Using the Keyboard The most common way of sending signals to processes is using the keyboard There are certain key presses that are interpreted by the system as requests to send signals to the process with which we are interacting: Ctrl-C Pressing this key causes the system to send an INT signal (SIGINT) to the running process By default, this signal causes the process to immediately terminate Ctrl-Z Pressing this key causes the system to send a TSTP signal (SIGTSTP) to the running process By default, this signal causes the process to suspend execution Ctrl-\ Pressing this key causes the system to send a ABRT signal (SIGABRT) to the running process By default, this signal causes the process to immediately terminate Note that this redundancy (i.e Ctrl-\ doing the same as Ctrl-C) gives us some better flexibility Sending Signals from the Command Line Another way of sending signals to processes is done using various commands, usually internal to the shell: kill The kill command accepts two parameters: a signal name (or number), and a process ID Usually the syntax for using it goes something like: kill - fg On most shells, using the 'fg' command will resume execution of the process (that was suspended with Ctrl-Z), by sending it a CONT signal Sending Signals Using System Calls #include /* standard unix functions, like getpid() */ #include /* various type definitions, like pid_t */ #include /* signal name macros, and the kill() prototype */ /* first, find my own process ID */ pid_t my_pid = getpid(); /* now that i got my PID, send myself the STOP signal */ kill(my_pid, SIGSTOP); Catchable and Non-Catchable Signals Some signals cannot be caught and handled by processes For example KILL which causes termination (from the shell: kill -9 …), STOP which causes suspension (can later be resumed with a CONT signal) Note STOP is not the signal generated by Ctrl+Z On the other hand, signals such as SEGV (notify of segmentation fault – meaning accessing illegal memory address) and BUS (notify of bus error – meaning accessing memory address with invalid alignment) are both catchable Default Signal Handlers There is a default signal handler for all signals For example the default handler for TERM is call the exit() system call The pause() System Call the pause() system call causes the process to halt execution, until some signal is received The signal() System Call usage: Signal( , ); Causes the next time the specified signal is received, to call the given function instead of the default function associated with that signal Example: #include /* standard I/O functions */ #include /* standard unix functions, like getpid() */ #include /* various type definitions, like pid_t */ #include /* signal name macros, and the signal() prototype */ /* first, here is the signal handler */ void catch_int(int sig_num) { /* re-set the signal handler again to catch_int, for next time */ signal(SIGINT, catch_int); /* and print the message */ printf("Don't that\n"); } /* set the INT (Ctrl-C) signal handler to 'catch_int' */ signal(SIGINT, catch_int); /* now, lets get into an infinite loop of doing nothing */ while (true) { pause(); } Pre-defined Signal Handlers SIG_IGN: Causes the process to ignore the specified signal signal(SIGINT, SIG_IGN); SIG_DFL: Causes the system to set the default signal handler for the given signal (i.e the same handler the system would have assigned for the signal when the process started running): signal(SIGTSTP, SIG_DFL); Example – Process communication: /***************************************************************************/ /* This program demonstrates sending signals between processes: */ /* The 'father' process creates two 'son' processes Trying to compute the */ /* same value The first to finish exits and the 'father' 'kills' its */ /* slow 'son' by sending a signal */ /***************************************************************************/ #include #include #include #include #include #include #include #include #include typedef struct _param int number; int sleep_time; } param; { //This function will be calld as a reaction to catching a signal void catchSigT(int sig_num) { printf("pid %d operated catchSigT\n",getpid()); signal(SIGTERM, catchSigT); }; void elegant_death(int sig_num) { printf("pid %d declares it's loss with dignity\n",getpid()); signal(SIGINT, catchSigT); exit(0); }; int pid1 = 1, pid2 = 1; //will hold the process id's of the sons int main (char **argv, int argc) { param param1, param2; param args; int * stat; int first,i; long result; param1.number = 10; preform the calculation param1.sleep_time = 2; each comutation loop param2.number = 10; preform the calculation param2.sleep_time = 7; each comutation loop //the number of times the first son will //the time that the first son will sleep in //the number of times the second son will //the time that the first son will sleep in //defining the catch of SIGINT and SIGTERM to activate the 'elegent_death' & 'catch sig' function signal(SIGTERM, catchSigT); signal(SIGINT, elegant_death); //forking the two sons pid1 = fork(); if(pid1 != 0) pid2 = fork(); //sons code if(pid1 == || pid2 == 0) { pause();//waiting for the father to begin the computation //updating the pointer to the right structure if(pid1 == 0) args = param1; else args = param2; //computing result = 1; for (i=1; i[...]...Example 3 output: Son - pid = 22 879 group leader = 22 878 Son - pid = 22 879 group leader = 22 879 can I get here? father pid = 22 878 father pid = 22 878 22 878 caught SIGINT Father - pid = 22 878 group leader = 22 878 Process Groups and Signals Signals sent from the keyboard (like by ctrl-C) are actually sent to the current ... 22 899 ready PID 22 900 ready PID 22 901 ready PID 22 9 02 ready PID 22 903 ready PID 22 903 caught PID 22 9 02 caught PID 22 901 caught PID 22 900 caught PID 22 899 caught 22 903 is dead 22 901 is dead 22 9 02. .. - pid = 22 879 group leader = 22 878 Son - pid = 22 879 group leader = 22 879 can I get here? father pid = 22 878 father pid = 22 878 22 878 caught SIGINT Father - pid = 22 878 group leader = 22 878 Process... PID 22 901 caught PID 22 900 caught PID 22 899 caught 22 903 is dead 22 901 is dead 22 9 02 is dead 22 899 is dead 22 900 is dead one one one one one execvp and Signal handlers Since the process image

Ngày đăng: 04/12/2015, 00:54

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w