APUE第十章学习笔记

前端之家收集整理的这篇文章主要介绍了APUE第十章学习笔记前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

1.信号

  1. /*****************************************
  2. 信号处理方式:
  3. (1):忽略此信号。(SIGKILL 和 SIGSTOP信号不能被忽略)
  4. (2):捕捉信号
  5. (3):执行系统默认动作
  6. *****************************************/
  7.  
  8. /*****************************************
  9. 包含头文件 #include <signal.h>
  10. 函数原型: void (*signal(int signo,void(*func)(int)))(int);
  11. 函数说明:signo是信号名,func的值是常量 SIG_IGN(忽略) SIG_DEL(系统默认动作) 或 当接到此信号后要调用函数地址
  12. 返回值:若成功,返回以前的信号处理配置,若出错,返回SIG_ERR
  13. *****************************************/
  14.  
  15. /****************************************
  16. exec函数将原先设置为要捕捉的信号都更改为默认动作,其他信号的状态则不变(一个进程原先要捕捉的信号,当其执行一个新程序后,就不能再不捕捉了)
  17. 子进程会继承父进程信号处理方式
  18. *****************************************/

vi 10.1.c

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <signal.h>
  4. #include <unistd.h>
  5.  
  6. static void sig_usr(int);
  7.  
  8. int main()
  9. {
  10. if (signal(SIGUSR1,sig_usr) == SIG_ERR)
  11. {
  12. printf("signal error\n");
  13. exit(0);
  14. }
  15.  
  16. if (signal(SIGUSR2,sig_usr) == SIG_ERR)
  17. {
  18. printf("signal error\n");
  19. exit(0);
  20. }
  21.  
  22. for (; ;)
  23. pause();
  24. return 0;
  25. }
  26.  
  27. static void sig_usr(int signo)
  28. {
  29. if (signo == SIGUSR1)
  30. printf("received SIGUSR1\n");
  31. else if (signo == SIGUSR2)
  32. printf("received SIGUSR2\n");
  33. else
  34. {
  35. printf("received signal %d\n",signo);
  36. exit(0);
  37. }
  38. }

vi 10.2.c

  1. include <stdio.h>
  2. #include <stdlib.h>
  3. #include <signal.h>
  4. #include <unistd.h>
  5.  
  6. static void sig_usr(int);
  7.  
  8. int main()
  9. {
  10. if (signal(SIGUSR1,sig_usr) == SIG_ERR)
  11. {
  12. printf("1: signal error\n");
  13. exit(0);
  14. }
  15.  
  16. if (signal(SIGUSR2,sig_usr) == SIG_ERR)
  17. {
  18. printf("2: signal error\n");
  19. exit(0);
  20. }
  21.  
  22. pid_t pid;
  23.  
  24. if ((pid = fork()) < 0)
  25. {
  26. printf("fork error\n");
  27. exit(0);
  28. }
  29. else if (pid == 0)
  30. {
  31. printf("子进程 ID: %d\n",getpid());
  32. for (; ;)
  33. pause();
  34. }
  35. else
  36. {
  37. printf("父进程 ID: %d\n",getpid());
  38. for (; ;)
  39. pause();
  40. }
  41. return 0;
  42. }
  43.  
  44. static void sig_usr(int signo)
  45. {
  46. if (signo == SIGUSR1)
  47. printf("reveived SIGUSR1\n");
  48. else if (signo == SIGUSR2)
  49. printf("received SIGUSR2\n");
  50. else
  51. {
  52. printf("received signo %d\n",signo);
  53. exit(0);

2.可重入函数

  1. /*****************************************
  2. 可重入函数: 在信号处理程序中保证调用安全的函数,这些函数是可重入的并称为异步信号安全的
  3. 不可重入函数一般有以下性质:
  4. (1):已知它们使用静态数据结构
  5. (2):它们调用malloc和free
  6. (3):它们是标准I / O函数
  7. *****************************************/
  8.  
  9. /*****************************************
  10. 当一个信号产生时,内核在进程表以某种形式设置一个标志,此时为向进程递送一个信号,在信号产生和递送之间的时间间隔内,称信号是未决的
  11. 如果进程产生了一个阻塞的信号,而且对该信号的动作是系统默认动作或捕捉该信号,则为该进程将此信号保持为未决状态,直到该进程对此信号解除了阻塞,或者将对此信号动作改成忽略
  12. *****************************************/

vi 10.3.c

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <signal.h>
  4. #include <pwd.h>
  5. #include <string.h>
  6. #include <unistd.h>
  7.  
  8. static void my_alarm(int signo)
  9. {
  10. struct passwd* rootptr;
  11.  
  12. printf("in signal handler\n");
  13.  
  14. if ((rootptr = getpwnam("root")) == NULL)
  15. {
  16. printf("getpwname(root) error\n");
  17. exit(0);
  18. }
  19.  
  20. alarm(1);
  21. }
  22.  
  23. int main()
  24. {
  25. struct passwd* ptr;
  26.  
  27. signal(SIGALRM,my_alarm);
  28. alarm(1);
  29.  
  30. for (; ;)
  31. {
  32. if ((ptr = getpwnam("marco")) == NULL)
  33. {
  34. printf("getpwnam error\n");
  35. exit(0);
  36. }
  37.  
  38. if (strcmp(ptr->pw_name,"marco") != 0)
  39. {
  40. printf("return value corrupted!,pw_name = %s\n",ptr->pw_name);
  41. }
  42. }
  43.  
  44. return 0;
  45. }

函数 kill 和 raise

  1. /********************************************************
  2. 包含头文件: #include <signal.h>
  3. 函数原型: int kill(pid_t pid,int signo);
  4. int raise(int signo);
  5. 函数说明: kill将信号发送给进程或进程组
  6. raise函数则允许进程自身发送信号
  7. kill: (1):若pid > 0,则发送signo至进程pid
  8. (2): 若pid == 0,则发送至同一进程组的所有进程(不包括实现的系统进程集)
  9. (3): 若 pid < 0,将该信号发送给进程组等于pid绝对值的所有进程(不包括实现的系统进程集)
  10. (4): 若pid == -1,将该信号发送给发送进程有权限发送的所有进程(不包括实现的系统进程集)
  11. raise: 允许进程向自身发送信号
  12. 返回值:若成功,返回0,若出错,返回-1
  13. ***********************************************************/

vi 10.4.c

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <signal.h>
  5.  
  6. static void sig_usr(int signo)
  7. {
  8. if (signo == SIGUSR1)
  9. printf("进程 %d 收到信号 SIGUSR1\n",getpid());
  10. else if (signo == SIGUSR2)
  11. printf("进程 %d 收到信号 SIGUSR2\n",getpid());
  12. else
  13. printf("进程 %d 收到信号 %d\n",getpid(),signo);
  14. }
  15.  
  16. int main()
  17. {
  18.  
  19. if (signal(SIGUSR1,sig_usr) == SIG_ERR)
  20. {
  21. printf("1: signal error\n");
  22. exit(0);
  23. }
  24.  
  25. if (signal(SIGUSR2,sig_usr) == SIG_ERR)
  26. {
  27. printf("2: signal error\n");
  28. exit(0);
  29. }
  30.  
  31. pid_t pid;
  32.  
  33. if ((pid = fork()) < 0)
  34. {
  35. printf("fork error\n");
  36. exit(0);
  37. }
  38. else if (pid == 0)
  39. {
  40. printf("子进程组ID: %d\n",getpgrp());
  41. pid_t pid2;
  42.  
  43. if ((pid2 = fork()) < 0)
  44. {
  45. printf("child fork error\n");
  46. exit(0);
  47. }
  48. else if (pid2 == 0)
  49. {
  50. printf("子进程子进程组ID: %d\n",getpgrp());
  51. pause();
  52. pause();
  53. exit(0);
  54. }
  55. sleep(4);
  56. pause();
  57. pause();
  58. exit(0);
  59. }
  60. sleep(6);
  61. printf("父进程进程组ID: %d\n",getpgrp());
  62. kill(0,SIGUSR1);
  63. kill(0,SIGUSR2);
  64. return 0;
  65. }
  1. /*******************************************************
  2. 包含头文件: #include <unistd.h>
  3. 函数原型: unsigned int alarm(usigned int seconds);
  4. 函数说明: 参数seconds的值是产生信号SIGALRM需要经过时钟秒数
  5. 每个进程只能有一个闹钟时间.如果在调用alarm时,之前已为该进程注册的闹钟时间还没有超时,则将该闹钟时间的余留值作为本次alarm函数调用的值返回,以前
  6. 注册的闹钟被新值代替
  7. 返回值: 0 或 以前设置的闹钟时间的余留秒数
  8. ********************************************************/
  9.  
  10. /*******************************************************
  11. 包含头文件: #include <unistd.h>
  12. 函数原型: int pause(void);
  13. 函数说明:使调用进程挂起直至捕捉到一个信号
  14. 返回值: -1,errno设置为 EINTR
  15. ********************************************************/

vi 10.5.c

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <signal.h>
  5.  
  6. static void sig_alarm(int signo)
  7. {
  8.  
  9. }
  10. unsigned int sleep1(unsigned int seconds)
  11. {
  12. if (signal(SIGALRM,sig_alarm) == SIG_ERR)
  13. return seconds;
  14.  
  15. alarm(seconds);
  16. pause();
  17. return alarm(0);
  18. }
  19. int main()
  20. {
  21.  
  22. sleep1(5);
  23. return 0;
  24. }

vi 10.5.1.c

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <setjmp.h>
  4. #include <signal.h>
  5. #include <unistd.h>
  6.  
  7.  
  8. static jmp_buf env_alrm;
  9.  
  10. static void sig_alarm()
  11. {
  12. longjmp(env_alrm,1);
  13. }
  14. unsigned int sleep2(unsigned int seconds)
  15. {
  16. if (signal(SIGALRM,sig_alarm) == SIG_ERR)
  17. return seconds;
  18. if (setjmp(env_alrm) == 0)
  19. {
  20. alarm(seconds);
  21. pause();
  22. }
  23. return (alarm(0));
  24. }
  25. int main()
  26. {
  27. sleep2(5);
  28. return 0;
  29. }

3.信号集

  1. /*******************************************************
  2. 包含头文件: #include <signal.h>
  3. 函数原型: int sigemptyset(sigset_t *set);
  4. int sigfillset(sigset_t *set);
  5. int sigaddset(sigset_t *set,int signo);
  6. int sigdelset(sigset_t *set,int signo);
  7. int sigismember(const sigset_t *set,int signo);
  8. 函数说明: sigemptyset 清除所有信号
  9. sigfillset 初始化所有信号
  10. sigaddset 增加特定信号
  11. sigdelset 删除特定信号
  12. sigismember 判断特定信号是否存在于信号集
  13. 返回值: sigemptyset sigfillset sigaddset sigdelset
  14. 若成功,返回0,返回-1
  15. sigismember 返回值: 若真,返回 1,若假,返回0
  16. *******************************************************/
  17.  
  18. /**********************************************************
  19. 包含头文件: #include <signal.h>
  20. 函数原型: int sigprocmask(int how,const sigset_t* restrict set,sigset_t *restrict oset);
  21. 函数说明:若set为空,则进程信号屏蔽字则通过oset返回
  22. 若set非空,则通过how来指示如何修改当前信号屏蔽
  23. how: SIG_BLOCK 取set 和 oset并集作为当前信号屏蔽
  24. SIG_UNBLOCK 取set 和 oset并集并解除set作为当前信号屏蔽
  25. SIG_SETMASK 将set值作为当前信号屏蔽
  26. 注:在调用sigprocmask后如果有任何未决的,不再阻塞的信号,则在sigprocmask返回前,至少将其中之一递送给该进程
  27. ***************************************************/

vi 10.6.c

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <signal.h>
  4. #include <unistd.h>
  5.  
  6. void sig_usr(int signo)
  7. {
  8. if (signo == SIGUSR1)
  9. printf("收到信号 SIGUSR1\n");
  10. else if (signo == SIGUSR2)
  11. printf("收到信号 SIGUSR2\n");
  12. else
  13. printf("收到信号 %d\n",signo);
  14. }
  15.  
  16. int main()
  17. {
  18. if (signal(SIGUSR1,sig_usr) == SIG_ERR)
  19. {
  20. printf("signal error\n");
  21. exit(0);
  22. }
  23.  
  24. if (signal(SIGUSR2,sig_usr) == SIG_ERR)
  25. {
  26. printf("signal error\n");
  27. exit(0);
  28. }
  29.  
  30. sigset_t oldmask,newmask;
  31.  
  32. if (sigemptyset(&oldmask) < 0 || sigemptyset(&newmask))
  33. {
  34. printf("sigemptyset error\n");
  35. exit(0);
  36. }
  37.  
  38. sigaddset(&oldmask,SIGUSR1);
  39.  
  40. printf("屏蔽信号 SIGUSR1\n");
  41.  
  42. sigprocmask(SIG_SETMASK,&oldmask,NULL);
  43. kill(getpid(),SIGUSR1);
  44. kill(getpid(),SIGUSR2);
  45. sleep(3);
  46. printf("\n");
  47.  
  48. printf("屏蔽信号 SIGUSR2\n");
  49.  
  50. sigaddset(&newmask,SIGUSR2);
  51. sigprocmask(SIG_SETMASK,&newmask,SIGUSR2);
  52. sleep(3);
  53. printf("\n");
  54.  
  55. printf("屏蔽信号 SIGUSR1 和 SIGUSR2\n");
  56.  
  57. sigprocmask(SIG_BLOCK,&oldmask);
  58. kill(getpid(),SIGUSR2);
  59.  
  60. return 0;
  61. }
  1. /*****************************************
  2. 包含头文件: #include <signal.h>
  3. 函数原型: int sigpending(sigset_t *set);
  4. 函数说明: 返回信号集,对于调用进程而言,其中的信号是阻塞不能递送的,因而也一定是当前未决的.
  5. 返回值: 若成功,返回-1
  6. *****************************************/

vi 10.7.c

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <signal.h>
  4. #include <unistd.h>
  5.  
  6. void sig_usr(int signo)
  7. {
  8. if (signo == SIGUSR1)
  9. printf("收到信号 SIGUSR1\n");
  10. else if (signo == SIGUSR2)
  11. printf("收到信号 SIGUSR2\n");
  12. else
  13. printf("收到信号 %d\n",sig_usr) == SIG_ERR)
  14. {
  15. printf("signal error\n");
  16. exit(0);
  17. }
  18. sigset_t mask,oldmask;
  19.  
  20. sigemptyset(&mask);
  21. sigaddset(&mask,SIGUSR1);
  22. //得到row 信号集
  23. sigprocmask(SIG_BLOCK,NULL,&oldmask);
  24. //屏蔽信号 SIGUSR1
  25. sigprocmask(SIG_SETMASK,&mask,NULL);
  26. //发送信号 SIGUSR1
  27. kill(getpid(),SIGUSR1);
  28. // 信号SIGUSR1 阻塞未决
  29. sigset_t getmask;
  30.  
  31. sigemptyset(&getmask);
  32. sigpending(&getmask);
  33.  
  34. if (sigismember(&getmask,SIGUSR1))
  35. printf("SIGUSR1 is mask\n");
  36. // 解除屏蔽信号 SIGUSR1
  37. sigprocmask(SIG_SETMASK,NULL);
  38. return 0;
  39. }

4.sigaction函数

  1. /*****************************************
  2. 包含头文件: #include <signal.h>
  3. 函数原型: int sigaction(int signo,const struct sigaction *restrict act,struct sigaction * restrict oact);
  4. 函数说明:参数signo是要检测或修改其具体动作的信号编号,若act非空,则修改其动作,如果oact非空,则系统由oact返回该信号的上一个动作
  5. 返回值:若成功,返回0,若失败,返回-1
  6.  
  7. strcut sigaction
  8. {
  9. void (*sa_handler)(int) ; //信号处理函数的地址
  10. sigset_t sa_mask; //增加需要阻塞的信号
  11. int sa_flags; //可选标志
  12. void (*sa_sigaction)(int,siginfo_t *,void *);
  13. //可替代信号处理程序
  14. }
  15.  
  16. struct siginfo
  17. {
  18. int si_signo; //信号编号
  19. int si_errno; //错误标志
  20. int si_code; //可添加代码
  21. pid_t si_pid; //传送进程ID
  22. uid_t si_uid; //传送进程实际用户ID
  23. void *si_addr; //造成错误的地址
  24. int si_status; //退出值或信号值
  25. union sigval si_value; //应用程序特殊值
  26. /* ………….. */
  27. };
  28.  
  29. union sigval
  30. {
  31. int sival_int;
  32. void* sival_ptr;
  33. };
  34. *****************************************/

vi 10.8.c

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <signal.h>
  5.  
  6. void sig_usr(int signo)
  7. {
  8. if (signo == SIGUSR1)
  9. printf("收到信号 SIGUSR1\n");
  10. else if (signo == SIGUSR2)
  11. printf("收到信号 SIGUSR2\n");
  12. else
  13. printf("收到信号 %d\n",signo);
  14. }
  15.  
  16. int main()
  17. {
  18. struct sigaction act;
  19. act.sa_handler = sig_usr;
  20.  
  21. if (sigaction(SIGUSR1,&act,NULL) < 0)
  22. {
  23. printf("sigaction error\n");
  24. exit(0);
  25. }
  26.  
  27. if (sigaction(SIGUSR2,NULL) < 0)
  28. {
  29. printf("sigaction error\n");
  30. exit(0);
  31. }
  32.  
  33. kill(getpid(),SIGUSR1);
  34. kill(getpid(),SIGUSR2);
  35.  
  36. return 0;
  37. }

vi 10.9.c

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <signal.h>
  4. #include <unistd.h>
  5.  
  6. typedef void Sigfunc(int);
  7.  
  8. Sigfunc * signal2(int signo,Sigfunc *func)
  9. {
  10. struct sigaction act,oact;
  11.  
  12. act.sa_handler = func;
  13. sigemptyset(&act.sa_mask);
  14.  
  15. act.sa_flags = 0;
  16.  
  17. if (signo == SIGALRM)
  18. {
  19. #ifdef SA_INTERRUPT
  20. act.sa_flags |= SA_INTERRUPT;
  21. #endif
  22. }
  23. else
  24. {
  25. act.sa_flags |= SA_RESTART;
  26. }
  27.  
  28. if (sigaction(signo,&oact) < 0)
  29. return (SIG_ERR);
  30.  
  31. return (oact.sa_handler);
  32. }
  33.  
  34. void sig_usr(int signo)
  35. {
  36. if (signo == SIGUSR1)
  37. printf("接收到信号 SIGUSR1\n");
  38. else
  39. printf("接收到信号 %d\n",signo);
  40. }
  41. int main()
  42. {
  43. if (signal2(SIGUSR1,sig_usr) == SIG_ERR)
  44. {
  45. printf("signal2 error\n");
  46. exit(0);
  47. }
  48.  
  49. kill(getpid(),SIGUSR1);
  50. return 0;
  51. }

4.sigsetjmp 和 siglongjmp函数

  1. /**********************************************************
  2. 包含头文件: #include <setjmp.h>
  3. 函数原型: int sigsetjmp(sigjmp_buf env,int savemask);
  4. 函数说明: 进行非局部转移并恢复所保存信号屏蔽
  5. 返回值:若直接调用,返回0;若从siglongjmp调用返回,则返回非0
  6.  
  7. void siglongjmp(sigjmp_buf env,int val);
  8. *********************************************************/

5.sigsuspend函数

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <signal.h>
  4. #include <unistd.h>
  5.  
  6. void sig_usr1(int signo)
  7. {
  8. printf("接收到信号 SIGUSR1\n");
  9. }
  10.  
  11. void sig_usr2(int signo)
  12. {
  13. printf("接收到信号 SIGUSR2\n");
  14. }
  15.  
  16.  
  17. int main()
  18. {
  19. if (signal(SIGUSR1,sig_usr1) == SIG_ERR)
  20. {
  21. printf("signal SIGUSR1 error\n");
  22. exit(0);
  23. }
  24.  
  25. if (signal(SIGUSR2,sig_usr2) == SIG_ERR)
  26. {
  27. printf("signal SIGUSR2 error\n");
  28. exit(0);
  29. }
  30.  
  31. sigset_t mask1,mask2;
  32. sigemptyset(&mask1);
  33. sigemptyset(&mask2);
  34. sigaddset(&mask1,SIGUSR1);
  35. sigaddset(&mask2,&mask1,NULL);
  36.  
  37. if (sigsuspend(&mask2) != -1)
  38. {
  39. printf("sigsuspend error\n");
  40. exit(0);
  41. }
  42.  
  43. kill(getpid(),SIGUSR2);
  44. return 0;
  45. }

6.函数system

vi 10.12.c

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <signal.h>
  4. #include <unistd.h>
  5. #include <errno.h>
  6. #include <sys/wait.h>
  7.  
  8. int system1(const char* cmdstring)
  9. {
  10. if (cmdstring == NULL)
  11. return 1;
  12.  
  13. struct sigaction ignore,saveintr,savequit;
  14. sigset_t chldmask,savemask;
  15.  
  16. ignore.sa_handler = SIG_IGN;
  17. sigemptyset(&ignore.sa_mask);
  18. ignore.sa_flags = 0;
  19.  
  20. if (sigaction(SIGINT,&ignore,&saveintr) < 0)
  21. {
  22. return -1;
  23. }
  24.  
  25. if (sigaction(SIGQUIT,&savequit) < 0)
  26. {
  27. return -1;
  28. }
  29.  
  30. sigemptyset(&chldmask);
  31. sigaddset(&chldmask,SIGCHLD);
  32.  
  33. if (sigprocmask(SIG_BLOCK,&chldmask,&savemask) < 0)
  34. return -1;
  35.  
  36. pid_t pid;
  37. int status;
  38.  
  39. if ((pid = fork()) < 0)
  40. status = -1;
  41. else if (pid == 0)
  42. {
  43. sigaction(SIGINT,&saveintr,NULL);
  44. sigaction(SIGQUIT,NULL);
  45. sigprocmask(SIG_SETMASK,&savemask,NULL);
  46.  
  47. execl("/bin/sh","sh","-c",cmdstring,(char*)0);
  48. _exit(127);
  49. }
  50. else
  51. {
  52. while (waitpid(pid,&status,0) < 0)
  53. if (errno == EINTR)
  54. {
  55. status = -1;
  56. break;
  57. }
  58. }
  59.  
  60. if (sigaction(SIGINT,NULL) < 0)
  61. return -1;
  62. if (sigaction(SIGQUIT,&savequit,NULL) < 0)
  63. return -1;
  64. if (sigprocmask(SIG_SETMASK,NULL) < 0)
  65. return -1;
  66. return status;
  67. }
  68.  
  69. int main()
  70. {
  71. system1("date");
  72. return 0;
  73. }

7.nanosleep

  1. /**********************************************************
  2. 包含头文件: #include <time.h>
  3. 函数原型: int nanosleep(const struct timespec *reqtp,struct timespec *remtp);
  4. 函数说明:挂起调用进程,直到要求时间超时或某个信号中断了该函数,reqtp指向休眠长度,remtp未休眠完时间长度
  5. 返回值:若休眠到要求的时间,返回-1
  6. **********************************************************/
  7.  
  8.  
  9.  
  10. /***********************************************************
  11. 包含头文件: #include <time.h>
  12. 函数原型: int clock_nanosleep(clockid_t clock_id,int flags,const struct timespec* reqtp,struct timespec* remtp);
  13. 函数说明: flags为0表示休眠时间是相对的,表示休眠reqtp时间,flags为 TIMER_ABSTIME,表示休眠时间是绝对的,表示休眠到reqtp
  14. **********************************************************/

vi 10.13.c

  1. #include <time.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <signal.h>
  5.  
  6. struct timespec* rest = NULL;
  7.  
  8. void sig_usr(int signo)
  9. {
  10. if (rest != NULL)
  11. {
  12. printf("剩于未休眠时间 秒数: %ld 纳秒数: %ld\n",rest->tv_sec,rest->tv_nsec);
  13. }
  14. }
  15.  
  16. int main()
  17. {
  18. if (signal(SIGUSR1,sig_usr) == SIG_ERR)
  19. {
  20. printf("signal SIGUSR1 error\n");
  21. exit(0);
  22. }
  23.  
  24. if (signal(SIGUSR2,sig_usr) == SIG_ERR)
  25. {
  26. printf("signal SIOGUSR2 error\n");
  27. exit(0);
  28. }
  29.  
  30. struct timespec set;
  31. set.tv_sec = 20;
  32. set.tv_nsec = 0;
  33. rest = (struct timespec*)(malloc(sizeof(struct timespec)));
  34. nanosleep(&set,rest);
  35. return 0;
  36. }

vi 10.14.c

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <signal.h>
  4. #include <time.h>
  5.  
  6. struct timespec* rest = NULL;
  7.  
  8. void sig_usr(int signo)
  9. {
  10. if (rest != NULL)
  11. {
  12. printf("休眠剩余时间: 秒数: %ld 纳秒数: %ld\n",sig_usr) == SIG_ERR)
  13. {
  14. printf("signal SIGUSR2 error\n");
  15. exit(0);
  16. }
  17.  
  18. struct timespec set;
  19. clock_gettime(CLOCK_REALTIME,&set);
  20. set.tv_sec += 40;
  21. rest = (struct timespec *)malloc(sizeof(struct timespec));
  22. clock_nanosleep(CLOCK_REALTIME,TIMER_ABSTIME,&set,rest);
  23. return 0;
  24. }

8.sigqueue函数

  1. /***********************************************************
  2. 包含头文件: #include <signal.h>
  3. 函数原型: int sigqueue(pid_t pid,int signo,const union sigval value);
  4. 函数说明:将信号发给单个进程,并附带value所传递值
  5. ***********************************************************/

vi 10.15.c

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <signal.h>
  4. #include <unistd.h>
  5.  
  6. void usr1_handler(int signo,siginfo_t *siginfo,void* context)
  7. {
  8. printf("接收到信号 SIGUSR1\n");
  9. printf("接收到附加信息是 %s\n",(char*)(siginfo->si_value.sival_ptr));
  10. }
  11.  
  12. int main()
  13. {
  14. struct sigaction usr1act;
  15.  
  16. usr1act.sa_sigaction = usr1_handler;
  17. usr1act.sa_flags = SA_SIGINFO;
  18. sigemptyset(&usr1act.sa_mask);
  19.  
  20. if (sigaction(SIGUSR1,&usr1act,NULL) < 0)
  21. {
  22. printf("sigaction SIGUSR1 error\n");
  23. exit(0);
  24. }
  25. union sigval value;
  26. value.sival_ptr = "SIGUSR1 的附加信息\n";
  27. if (sigqueue(getpid(),SIGUSR1,value) < 0)
  28. {
  29. printf("sigqueue error\n");
  30. exit(0);
  31. }
  32. return 0;
  33. }

猜你在找的Bash相关文章