APUE学习笔记——10.15 sigsetjmp和siglongjmp

转载自:sigsetjmp用法

侵犯您的权益,请联系:windeal12@qq.com

 

sigsetjmp用法

分类: c/c++ linux   1252人阅读  评论(0)  收藏  举报
相关函数:longjmp, siglongjmp, setjmp 
表头文件:#include <setjmp.h> 
函数定义:int sigsetjmp(sigjmp_buf env, int savesigs) 
函数说明:sigsetjmp()会保存目前堆栈环境,然后将目前的地址作一个记号,
而在程序其他地方调用siglongjmp()时便会直接跳到这个记号位置,然后还原堆栈,继续程序的执行。 
参数env为用来保存目前堆栈环境,一般声明为全局变量 
参数savesigs若为非0则代表搁置的信号集合也会一块保存 
当sigsetjmp()返回0时代表已经做好记号上,若返回非0则代表由siglongjmp()跳转回来。 
返回:若直接调用则为0,若从siglongjmp调用返回则为非0

实例:

[cpp]  view plain copy
  1. #include <stdio.h>  
  2. #include <signal.h>  
  3. #include <setjmp.h>  
  4. #include <unistd.h>  
  5. #include <sys/time.h>  
  6.   
  7. sigjmp_buf jmp_env;  
  8.   
  9. static void connect_alarm(int)  
  10. {  
  11.     siglongjmp(jmp_env, 1);  
  12. }  
  13.   
  14. int main()  
  15. {  
  16.     // 当超时时间sec_timeout大于等于运行时间run_time时会跳过printf("running...\n");  
  17.     int sec_timeout = 3;  
  18.     int run_time = 2;  
  19.   
  20.     printf("timeout = %d, run time = %d\n", sec_timeout, run_time);  
  21.     if (sec_timeout)  
  22.     {  
  23.         // 超过用alarm函数设置的时间时产生此信号,调用connect_alarm函数  
  24.         signal(SIGALRM, connect_alarm);  
  25.         alarm(sec_timeout);  
  26.         printf("set timeout\n");  
  27.         if (sigsetjmp(jmp_env, 1))  
  28.         {  
  29.             printf("timeout\n");  
  30.             goto out;  
  31.         }  
  32.     }  
  33.   
  34.     sleep(run_time);  
  35.     printf("running...\n");  
  36.   
  37. out:  
  38.     if (sec_timeout)  
  39.     {  
  40.         // 取消先前设置的闹钟  
  41.         alarm(0);  
  42.         printf("cancel timeout\n");  
  43.     }  
  44.   
  45.     return 0;  
  46. }  

程序运行:
当ec_timeout = 3, run_time = 2时:
timeout = 3, run_time = 2
set timeout
running...
cancel timeout


当ec_timeout = 3, run_time = 4时:
timeout = 3, run_time = 4
set timeout
timeout
cancel timeout



### APUE 第三章 学习笔记 #### 文件 I/O 基础 APUE 的第三章主要讨论了 Unix 系统中的文件 I/O 操作基础。这一章节涵盖了多个重要的概念技术细节,对于理解如何高效地操作文件至关重要。 #### 打开关闭文件 为了打开一个文件,程序通常会使用 `open` 或者 `creat` 函数[^1]。这两个函数都返回一个小于零的整数作为错误指示,而成功的调用则返回一个非负整数表示新创建的文件描述符。当不再需要访问某个特定文件时,应该通过调用 `close` 来关闭它。这不仅释放了与该文件关联的操作系统资源,而也使得这个文件描述符能够被重新利用。 ```c #include <fcntl.h> /* For O_* constants */ #include <unistd.h> /* For open(), close() */ int fd; fd = open("example.txt", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); if (fd >= 0) { // File opened successfully. } // Later... close(fd); ``` #### 文件读写 一旦有了有效的文件描述符,就可以对其进行读取 (`read`) 写入 (`write`) 操作。这些基本的 I/O 操作允许应用程序直接处理底层的数据流而不必关心具体的设备特性[^2]。 ```c char buffer[BUFSIZ]; ssize_t n; n = read(fd, buffer, BUFSIZ - 1); if (n > 0) { buffer[n] = '\0'; // Null terminate the string printf("%s\n", buffer); } const char *msg = "Hello world!"; write(fd, msg, strlen(msg)); ``` #### 文件定位 除了简单的顺序读写外,还可以改变当前文件偏移量来实现随机访问。这是通过 `lseek` 实现的功能之一,它可以向前或向后移动文件指针的位置以便从不同的位置开始读写数据[^3]。 ```c off_t offset; offset = lseek(fd, SEEK_SET, 0); // Move to beginning of file if (offset != -1L) { // Seek succeeded. } ``` #### 特殊文件类型的支持 Unix 系统支持多种特殊类型的文件对象,比如管道、套接字以及终端设备等。本章还介绍了针对这些不同类型文件的具体 API 接口支持机制[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值