Sleep function and signal mapping function

    The following 3 functions can make the process sleep for the specified time (with a delay).
#include <unistd.h>
unsigned int sleep(unsigned int second); /* Return value: 0 or the number of seconds to sleep*/
#include <time.h>
int nanosleep(const struct timespec *reqtp, struct timespec *remtp);
                       /* Return value: if sleep for the required time, return 0; if there is an error, return -1 */
int clock_nanosleep(clockid_t clock_id,int flags,const struct timespec *reqtp,struct timespec *remtp);
                   /* Return value: if sleep for the required time, return 0; if error, return error code*/

    The sleep function suspends the process until seconds seconds elapse or the calling process catches a signal and returns from the signal handler.
    The nanosleep function is similar to sleep, but provides nanosecond precision. The reqtp parameter specifies the length of time to sleep in seconds and nanoseconds, and the remtp parameter represents the length of time that does not sleep. If you are not interested, you can set it to NULL. The nanosleep function doesn't involve generating any signals, so you don't need to worry about interacting with other functions.
    The clock_nanosleep function uses a delay time relative to a specific clock to suspend the calling thread. The clock_id parameter specifies the clock on which the delay time is calculated. The flags parameter controls whether the delay is relative (when set to 0) or absolute (when set to TIMER_ABSTIME). reqtp and remtp are the same as nanosleep functions. However, when using absolute time, the remtp parameter is not used because it is not necessary. The same value of the reqtp parameter can be reused for other clock_nanosleep calls until the clock reaches the specified absolute time value.
    The following program is an implementation of the POSIX.1 sleep function that handles signals reliably and avoids race conditions in earlier implementations, but still does not handle interactions with previously set alarms (POSIX.1 does not explicitly address these interaction is defined).
#include <unistd.h>
#include <signal.h>

static void sig_alrm(int signo){
	;	// nothing to do, just returning wakes up sigsuspend().
}

unsigned int sleep(unsigned int seconds){
	unsigned int	unslept;
	struct sigaction	act, oldact;
	sigset_t newmask, oldmask, susmask;

	/* set handler, save previous information */
	act.sa_handler = sig_alrm;
	sigemptyset (& act.sa_mask);
	act.sa_flags = 0;
	sigaction(SIGALRM, &act, &oldact);

	/* block SIGALRM and save current signal mask */
	sigemptyset (& newmask);
	sigaddset (& newmask, SIGALRM);
	sigprocmask (SIG_BLOCK, & newmask, & oldmask);
	
	alarm(seconds);
	susmask = oldmask;
	sigdelset(&susmask, SIGALRM);	// make sure SIGALRM isn't blocked
	sigsuspend(susmask);	// wait for any signal to be caught

	/* some signal has been caught, SIGALRM is now blocked */
	unslept = alarm(0);
	/* reset previous action */
	sigaction(SIGALRM, &oldact, NULL);
	/* reset signal mask, which unblocks SIGALRM */
	sigprocmask (SIG_SETMASK, & oldmask, NULL);
	return unslept;
}


    The following functions can be used to query the mapping relationship between signal numbers and signal names.
#include <signal.h>
void psignal(int signo, const char *msg);
void psiginfo(const siginfo_t *info, const char *msg);
#include <string.h>
char *strsignal(int signo); /* return value: pointer to a string describing the signal */

// provided by Solaris
#include <signal.h>
int sig2str (int sign, char * str);
int str2sig(const char *str, int *signop);
                      /* Return value: if successful, return 0; otherwise, return -1 */

    The psignal function portably prints the string corresponding to the signal number. The argument msg (usually the program name) is output to the standard error file, followed by a colon and a space, followed by a description of the signal, and finally a newline. If msg is NULL, only the signal description section is output to the standard error file, similar to perror.
    If you have a siginfo structure in the sigaction signal handler, you can use the psiginfo function to print signal information. It is similar to the psignal function, but provides access to more information than the signal number, which may vary from platform to platform.
    If you only need the character description part of the signal, and don't need to write it to the standard error file (such as to a log file), you can use the strsignal function, which is similar to strerror.
    The sig2str and str2sig functions are provided by Solaris. sig2str translates the given signal number into a string and stores it in the memory area pointed to by str, removing the "SIG" prefix from the signal name. str2sig translates the given signal name into a signal number and stores it in the integer pointed to by signop, which is either a signal name without the "SIG" prefix, or a string representing a decimal signal number (such as "9") . Note that neither function sets errno when it fails.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326222346&siteId=291194637