Create two sub-processes;
Child Process 1 writes to the file Mytest.txt,
Write once every 5 seconds,
The time at which the write was made.
Sub-process 2 reads the file Mytest.txt,
Read once every 5 seconds,
Reads and prints the most recent time written in the file.
Both read and write operations are protected with file locks.
Main.c
time_t Currtime;
Time (&currtime);
Char *time_string = CTime (&currtime);
Signal
What is a signal?
A signal is an event.
Cannot customize the signal, all signals are system-predefined.
Who produces the signal?
1) A corresponding signal is generated by the shell terminal based on the current error (segment error, illegal instruction, etc.)
Like what:
Socket communication or pipeline communication,
If the read end has been closed,
Perform a write operation (or send data),
The process that will cause the write operation to receive the sigpipe signal
(indicates pipe breakage)
The default behavior of the signal: terminates the process.
2) at the shell terminal, use the kill or Killall command to generate the signal
Example: main1.c
./a.out &
Kill-hup 13733/* Send sighup to process with PID 13733 */
3) in the program code, call the kill system call to generate a signal
- What are the signal name descriptions?
Sigabort process abnormally terminated
SIGALRM Timeout Alarm
SIGFPE floating-point arithmetic exception
SIGHUP connection hangs off
Sigill illegal Instructions
SIGINT terminal Interrupt (CTRL + C will generate the signal)
SIGKILL * Terminate Process
Sigpipe writing data to a pipeline that does not have a read process
Sigquit Terminal exit (ctrl+\ will generate this signal)
SIGSEGV Invalid memory segment access
SIGTERM termination
SIGUSR1 * User definable signal 1
SIGUSR2 * User definable signal 2
———————————— –> above signal if not captured, the process will terminate after receiving it!
SIGCHLD child process has stopped or exited
Sigcont * Let the paused process continue execution
SIGSTOP * Stop execution (i.e. "pause")
SIGTSTP Interrupt Hangs
Sigttin Background Process attempt read operation
Sigttou background process attempts to write
Capture of Signals
The capture of a signal means that the specified function is executed after a signal has been received.
Note: Sigkill and sigstop cannot be captured,
That is, the response action of these two signals cannot be changed.
Installation of the signal
1) Use signal
Usage: Man 2 signal
typedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler);注:signal的返回类型,和它的第二个参数,都是函数指针类型signal的参数2可去以下特殊值:SIG_IGN 忽略信号SIG_DFL 恢复默认行为实例:main2.c 改变终端中断信号的行为此时就不能结束该进程了!只能通过其他终端,给该进程发送一个其他信号,使它终止 #ps ax | grep ./a.out //查询进程号 #kill -HUP 进程号 恢复信号的默认行为main3.c使用SIG_DFL时, 仅当第一次调用自定义的行为后 马上使用SIG_DFL就可恢复, 如果连续捕获多次后,就不确定。
2) Use Sigaction
The difference between sigaction and signal:
Sigaction is more "robust" than signal, it is recommended to use Sigaction
Usage: Man 2 sigaction
Structural struct sigaction
struct Sigaction {
void (Sa_handler) (int);/ signal response function */
sigset_t Sa_mask; /* Mask Signal set */
int sa_flags; /* When the sa_flags contains Sa_resethand, the signal is received and called
* After the specified signal processing function is executed, the response behavior of the signal is reset to the default behavior SIG_DFL */
...
}
补充:当sa_mask包含某个信号A时, 则在信号处理函数执行期间,如果发生了该信号A, 则阻塞该信号A(即暂时不响应该信号), 直到信号处理函数执行结束。 即,信号处理函数执行完之后,再响应该信号A实例:main4.c 用sigaction改变响应动作 即:用sigaction改写main2.c main5.c 用sigaction恢复默认动作 用sigaction改写main3.c
Sending of signals
How to send the signal:
Create a signal with a shortcut key in the shell terminal
Use the Kill,killall command.
Using the Kill function and the alarm function
1) Use the Kill function
Sends a specified signal to the specified process
Usage: Man 2 kill
Attention:
"Permissions" are required to send a signal to the specified process:
Normal user processes can only send signals to other processes of that user
Root user can send signals to all users ' processes
Kill failed
Return on Failure-1
Reason for failure:
Insufficient authority
Signal not present
The specified process does not exist
实例:main6.c 创建一个子进程 子进程每秒中输出字符串“child process work!" 父进程等待用户输入, 如果用户按下字符A, 则向子进程发信号SIGUSR1, 子进程的输出字符串改为大写 如果用户按下字符a, 则向子进程发信号SIGUSR2, 子进程的输出字符串改为小写
Example: MAIN7.C
Alarm Clock
Create a child process
The child process sends a SIGALRM to the parent process after 5 seconds
"Alarm" (simulated with print) after the parent process receives the SIGALRM signal
2) using the alarm function
Function: Sends a SIGALRM signal to the process itself within a specified time.
Usage: Man 2 alarm
Note: The unit of time is "seconds"
The actual alarm time is a little larger than the specified time.
If the parameter is 0, the set alarm is canceled.
If the alarm time is not reached and the alarm is called again, the alarm will be re-timed
You can use at most one alarm per process.
返回值: 失败:返回-1 成功:返回上次闹钟的剩余时间(秒)实例:“闹铃” main8.c 用alarm改写main7.c
3) Use Raise
Send a signal to the process itself.
Prototype: int raise (int sig)
Send multiple signals:
某进程正在执行某个信号对应的操作函数期间(该信号的安装函数),如果此时,该进程又多次收到同一个信号(同一种信号值的信号),则: 如果该信号是不可靠信号(<32),则只能再响应一次。 如果该信号是可靠信号(>32),则能再响应多次(不会遗漏)。 但是,都是都必须等该次响应函数执行完之后,才能响应下一次。
A process is executing a signal corresponding to the operation function (the signal's installation function),
If at this point the process receives another signal (a signal with a different signal value), then:
If the signal is contained in the Signaction Sa_mask (signal Shield set) of the current signal,
The signal is not processed immediately.
The processing function of the signal is not executed until the current signal processing function is executed.
Otherwise:
Immediately interrupts the current execution (if you are sleeping, such as sleep, it is immediately awakened)
And go to perform this new signal response.
After the new response has been executed, the signal handler function returned to the original is executed.
例:main4_2.c
Signal Set
1). What is a signal set
The signal set, represented by the sigset_t type, is essentially an unsigned long shaping.
Used to represent a collection that contains multiple signals.
2). Basic operation of the signal set
Sigemptyset, clear the signal set.
Sigfillset fills all defined signals into the specified set of signals
Sigdelset removes the specified signal from the specified set of signals
Sigaddset adds the specified signal from the specified signal set
sigismember 判断指定的信号是否在指定的信号集中 如果是, 返回 1 如果不是, 返回 0 信号无效, 返回-1详细用法见
3) "Signal shielding word" of the process
The "signal shielding word" of a process is a signal set
When a signal is sent to the target process, if the signal is in the signal screen word of the target process,
The target process will not capture the signal, that is, the processing function of the signal will not be executed.
When the signal screen word of the process no longer contains the signal, it captures the long-received signal (executes the corresponding function)
修改进程的“信号屏蔽字”使用sigprocmaskint sigprocmask(int how, const sigset_t *set, sigset_t *oldset);参数: how: SIG_BLOCK 把参数set中的信号添加到信号屏蔽字中 SIG_UNBLOCK 把参数set中的信号从信号屏蔽字中删除 SIG_SETMASK 把参数set中的信号设置为信号屏蔽字 oldset 返回原来的信号屏蔽字 例:main4_3.c
4) Get the signal that is not processed
When a signal in the signal screen word of a process occurs, these signals are not answered by the process,
These signals that have occurred but have not been processed can be obtained through the sigpending function.
Usage: Man sigpending
Return value: Success returns 0
Failure is returned-1
5) block-type wait signal
(1) Pause
Blocks the process until either signal occurs
(2) Sigsuspend
Sets the signal mask Word with the specified parameters, and then waits for the signal to be reversed when blocking.
That is, only wait for signals outside the signal shielding word
6) Use the SA_FLAGS flag in the sigaction structure
sigaction function parameters using a struct sigaction
struct sigaction structure with Sa_flags flag:
Sa_ Resethand the specified signal processing function is executed,
resets the response behavior of the signal to the default behavior SIG_DFL
Sa_nocldstop the child process stops without generating a sigchld signal
Sa_nodefer by default, When the processing function of a signal is executing, the
signal is added to the signal screen word of the process,
to prevent the current signal processing function from being processed, and the signal handler function will run again if the signal is not finished.
after the processing function of the signal is executed, the signal is removed from the signal screen word of the process.
The reason for the default settings above: If the signal processing function is "non-reentrant", it will be interrupted and executed again, resulting in an error! The above default setting avoids repeated occurrences of the same signal and causes the signal processing function to be Repeated execution of the case. If you use Sa_nodefer, the signal will not be added to the signal screen word. Sa_restart by default, an interruptible Linux system call will return an error during execution if a signal is received. and set errno to Eintr if you use Sa_restart, After the signal processing function is executed, the system call that is interrupted by the signal is re-executed, not a simple Returns an error on a single ground.
"Reentrant" function
In a signal processing function, you should only invoke a function that is reentrant.
Because the signal processing function is likely to be interrupted during execution.
A non-reentrant function ends when the last run is incomplete.
When you run again, problems can occur!
For example, the printf function is not reentrant.
So in the signal processing function, printf should not be called
解决办法: 在信号处理函数中,设置一个标志, 在信号处理函数之外去判断这个标志, 根据这个标志的状态来使用printf