Linux programming learning notes (15th) process control file lock signal processing and shielding

Source: Internet
Author: User
Tags flock
Document directory
  • 1.1 process, default Signal Processing
  • 1.2 process, user Signal Processing
  • 1. signal shielding
  • 2. signal shielding Switching
1. Basic control of a process 1. Common control functions of a process 1.1. Why do we need to control a process? 1.2 sleep pause/sleep/usleep1.3 on_exit atexit

Int atexit (void (* function) (void ));
Int on_exit (void (* function) (INT, void *), void * Arg );
Register a function and call it before calling exit or main function return.
The atexit function is simple and has no parameters.
In the on_exit function, Int Is the return value of exit or rerurn (1 byte does not require macro parsing), void * is the later ARG

It can be registered multiple times, but only called once.
The multi-process neutron process copies the registration, but once it is run, all other processes are canceled.

#include <stdio.h>#include <stdlib.h>void func(){printf("before over\n");}int main(){printf("Process\n");atexit(func);return 0;}

#include <stdio.h>#include <stdlib.h>void func(int statue,void *args){printf("before over\n");printf("statue = %d\n",statue);printf("args = %s\n",(char *)args);}int main(){printf("Process\n");char *str = "hello";on_exit(func,(void *)str);return 99;}

Zhao @ Ubuntu :~ /Unix/6 $./A. Out
Process
Before over
Statue = 99
ARGs = Hello

2 process and file lock

File read/write is shared in multiple processes.
Q: How do I know that a file is being read and written by another process?
Solution: filelock (default is recommended to force the lock to re-compile the kernel)
API:
Fcntl (file lock is affected by kernel parameters)
Programming Skills:
Lock files
Determine whether a file has a lock
Function Description:
Int fcntl (
Int FD, // The file descriptor to be locked
Int cmd, // Lock Operation Method: f_setlk (if the lock is applied, an exception is returned) f_setlkw (if the lock is applied, wait) f_unlk (unlock)
Struct flock * FK // lock description
);

Struct flock {
...
Short l_type;/* type of lock: f_rdlck,
F_wrlck, f_unlck */
Short l_whence;/* how to interpret l_start:
Seek_set, seek_cur, seek_end */
Off_t l_start;/* Starting offset for Lock */
Off_t l_len;/* number of bytes to lock */
Pid_t l_pid;/* PID of process blocking our lock
(F_getlk only )*/
...
};

Lock

# Include <unistd. h> # include <fcntl. h> # include <stdlib. h> # include <stdio. h> int main () {int FD; struct flock LK = {0}; // open the file FD = open ("test", o_rdwr | o_creat, 0666 ); if (FD =-1) {printf (": % m \ n"), exit (-1);} // description lock LK. l_type = f_wrlck; LK. rochelle whence = seek_set; LK. rochelle start = 5; LK. rochelle Len = 10; // lock int r = fcntl (FD, f_setlk, & lk); If (r = 0) printf ("locked successfully \ n "); else {printf ("failed to lock \ n") ;}while (1); // automatically unlocked after the program ends}

Note that the lock is only applied to 5 to 10. When the lock area is different, another lock can be successfully added.
Otherwise, the lock fails.

Read lock

# Include <stdio. h> # include <stdlib. h> # include <unistd. h> # include <fcntl. h> int main () {int FD; struct flock LK = {0}; // The lock FD = open ("test", o_rdwr) cannot be obtained without initialization ); if (FD <0) {printf (": % m \ n"), exit (-1);} int r = fcntl (FD, f_getlk, & lk ); // f_getlkif (r = 0) {printf ("successful lock \ n");} else {printf ("failed to get lock \ n");} If (LK. l_type = f_wrlck) {printf ("Write lock \ n");} printf ("START: % d, Len % d \ n", LK. rochelle start, LK. rochelle Len );}

Unlock

# Include <unistd. h> # include <fcntl. h> # include <stdlib. h> # include <stdio. h> int main () {int FD; struct flock LK = {0}; // open the file FD = open ("test", o_rdwr | o_creat, 0666 ); if (FD =-1) {printf (": % m \ n"), exit (-1);} // description lock LK. l_type = f_wrlck; LK. rochelle whence = seek_set; LK. rochelle start = 20; LK. rochelle Len = 10; // lock int r = fcntl (FD, f_setlk, & lk); If (r = 0) printf ("locked successfully \ n "); else {printf ("failed to lock \ n");} Sleep (3 );/*... Operate on files... */LK. l_type = f_unlck; r = fcntl (FD, f_setlk, & lk); If (r = 0) printf ("unlocked \ n "); else {printf ("unlock failed \ n ");}}

Note that these are only recommended locks. Even if you read the lock or the lock fails, you can perform operations on the file.

Functions of the Second-signal 1 signal

Notify other processes accordingly. A communication mechanism between processes.

The process that receives the signal immediately stops and executes the signal processing function. (Soft Interrupt)

1.1 process, default Signal Processing
# Include <unistd. h> # include <stdio. h> # include <signal. h> int main () {While (1) {printf ("process executing \ n"); sleep (1 );}}

How to send a signal: Kill-S signal process ID
Kill-S 1 7038 // send signal 1 to process 7038
Kill-s sigup 7038 // use the macro of the signal
Kill-l view all signals

The process is being executed.
The process is being executed.
The process is being executed.
The process is being executed.
The process is being executed.
Pending

CTRL + C is equivalent to sending signal 2 SIGINT interrupt signal

1.2 process, user Signal Processing

A process can only bind one function.
A function can be bound to multiple processes.

# Include <unistd. h> # include <stdio. h> # include <signal. h> void handle (INT s) {printf ("I am signal % d \ n", S); sleep (2 );} // After the function is returned, the main process continues int main () {signal (SIGINT, handle); // register the signal processing function while (1) {printf ("the process is running \ n"); sleep (1 );}}

The process is being executed.
^ C I am Signal 2
The process is being executed.
^ C I am Signal 2
The process is being executed.
^ C I am Signal 2
The process is being executed.
The process is being executed.
The process is being executed.

We found that Ctrl + C sent Signal 2.
Kill-S 9 is unavailable

Note: The signal sigkill sigstop cannot be processed

2 signal transmission and installation,

Int kill (pid_t PID, int sig); // sends the SIG signal to the process PID
Process ID:
> 0 sends a signal to a specified process
= 0 send signals to all processes in the process group where the process is located
-1 send all processes without init
<-1 send to the specified process group (group ID = absolute value)

#include <unistd.h>#include <stdio.h>#include <signal.h>#include <sys/types.h>int main(){while(1){kill(7323,SIGINT);sleep(5);}}
3. Application of signal 3.1

Sigalrm
Signal generation function alarm

3.2 Timer

Int setitimer (INT which, // Timing Method itimer_real itmer_virtual itimer_pro
Const struct itimerval * val, // time parameter of the timer
Struct itimer * oldval); // returns the previously set timer.

Itimer_real: calculated based on the real time of the system. It sends the sigalrm signal. (Common)
Itimer_virtual:-calculate the time spent by the process in the user State, and it sends the sigvtalrm signal.
Itimer_prof: calculates the time spent by the process in the user and kernel modes, and sends the sigprof signal.

Struct itimerval {
Struct timeval it_interval;/* Next value */Interval
Struct timeval it_value;/* Current Value */Delay Time
};

Struct timeval {
Long TV _sec;/* seconds */
Long TV _usec;/* microseconds */
};

Oldval can be set to null without receiving

# Include <signal. h> # include <stdio. h> # include <unistd. h> # include <sys/time. h> void deal (INT s) {printf ("Get up! \ N ") ;}int main () {signal (sigalrm, deal); struct itimerval v = {0}; // creates a struct and has two struct v. it_interval. TV _sec = 3; V. it_interval. TV _usec = 1; V. it_value. TV _sec = 5; V. it_value. TV _usec = 0; // The sigalrm signal setitimer (itimer_real, & V, null) is sent every 3 seconds after 5 seconds; while (1 ){}}
4. Signal Reliability and reliability and meaning

Signal loss (signal compression)
Due to history: signal compression is required
Reliable signal (real-time signal) and unreliable signal (non-real-time signal)

Early 1-31 31 signals are unreliable (related to the system, the system will generate ).
SIGUSR1 sigusr2 was left in the first 31 to be used by users.
Post-signal 34-64 31, reliable signal (user signal)
Dealing with systems, using early signals
Process User-Generated signals and use reliable signals

5 signal operation 1 signal shielding

Int sigprocmask (INT how, // operation method: sig_block blocked sig_unblock unblocked sig_setmask modified mask
Const sigset_t * Set, // Signal Set of the operation
Sigset_t * oldset); // returns the original blocked set.
Procedure
1. Declare a Signal Set
Sigset_t Sigs;
2 add shielded Signals
Signal shielding function
Clear sigemptyset
Add signals to the set sigaddset
Remove signal sigdelset from set
Add all signals to sigfillset
Judge whether the signal is in the Set sigismember

Int sigemptyset (sigset_t * Set );
Int sigfillset (sigset_t * Set );
Int sigaddset (sigset_t * Set, int SIGNUM );
Int sigdelset (sigset_t * Set, int SIGNUM );

Int sigismember (const sigset_t * Set, int SIGNUM );

Query signals in queue (signals received but blocked by sigprocmask)

Int sigpending (sigset_t * Set );

Sigpending () returns the set of signals that are pending for delivery
To the calling thread (I. e., the signals which have been raised while
Blocked). The mask of pending signals is returned in set.

# Include <stdio. h> # include <signal. h> int main () {sigset_t Sigs; // shield the set sigset_t SIG; sigemptyset (& SIGs); // clear the set sigemptyset (& sig ); // clear the set sigaddset (& Sigs, SIGINT); // sigprocmask (sig_block, & Sigs, 0); // start shielding int sum = 0; int I; for (I = 1; I <= 10; I ++) {sum + = I; sleep (1); sigpending (& sig ); // query the signal in queue (BLOCKED) if (sigismember (& Sig, SIGINT) {printf ("SIGINT is queuing! \ N ") ;}} printf (" sum = % d \ n ", sum); sigprocmask (sig_unblock, & Sigs, 0); // unblock printf (" over! \ N ");}
2. signal shielding Switching

Sigsuspend signal shielding Switching
Int sigsuspend (const sigset_t * mask );
Sigsuspend temporarily replaces the current blocked signal, and then suspends the process until a signal is sent, a signal processing program is called, or the process is terminated.

1 If the signal terminates this process, sigsuspend will not return.
2. if the signal is captured, after processing the signal processing function, sigsuspend () returns and restores the previously shielded signal.

Sigkill or sigstop cannot be blocked

The main function of this function is to limit the interrupt to a certain range. For example, the interruption caused by signal may occur anywhere.

# Include <stdio. h> # include <signal. h> void handle (INT s) {printf ("SIGINT processing \ n");} int main () {signal (SIGINT, handle); sigset_t sigp, sigq, Sigs; sigemptyset (& sigp); sigemptyset (& sigq); sigemptyset (& SIGs); sigaddset (& sigp, SIGINT); sigprocmask (sig_block, & sigp, 0 ); printf ("blocked SIGINT start \ n"); int I = 0, sum = 0; For (; I <10; I ++) {sum + = I; sleep (1); sigpending (& sigq); // obtain the signal in the queue if (sigismember (& sigq, SIGINT) {printf ("SIGINT queuing \ n "); sigsuspend (& SIGs); // only the interrupt printf ("SIGINT processing ended \ n") of SIGINT can be generated here ");}}}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.