本文将为您提供关于UNIX编程专题-POSIX信号的详细介绍,我们还将为您解释unix信号量的相关知识,同时,我们还将为您提供关于32547unix编程、c–POSIX信号行为、c–posix信号量的
本文将为您提供关于UNIX编程专题-POSIX信号的详细介绍,我们还将为您解释unix 信号量的相关知识,同时,我们还将为您提供关于32547 unix编程、c – POSIX信号行为、c – posix信号量的Sys V SEM_UNDO等价物、c – 在类中初始化静态POSIX信号量的实用信息。
本文目录一览:- UNIX编程专题-POSIX信号(unix 信号量)
- 32547 unix编程
- c – POSIX信号行为
- c – posix信号量的Sys V SEM_UNDO等价物
- c – 在类中初始化静态POSIX信号量
UNIX编程专题-POSIX信号(unix 信号量)
当我写此篇博客的时候,突然发现一片写得很到位的文章,所以。。
https://www.ibm.com/developerworks/cn/linux/l-ipc/part2/index1.html#authorN1001A
1.什么是POSIX信号
- 信号是一种软件中断(ps:在connect函数的第二种出错情况是一种硬件中断,见基本tcp套接字编程)。
- 很多重要的应用程序都需要提供处理信号的代码(在一些高级语言编程中可能很少涉及这方面,要注意)
- 信号提供了一种处理异步事件的方法(信号机制也是一种较为简单的进程间通信的一种机制)
每个信号都有一个名字,以SIG开头。不同操作系统可能支持的信号略有区别。
- 在头文件<bits/signum.h>中,信号名都被定义为正整数常量,不存在编号为0的信号(以下是ubuntu14.04支持的信号)
- 信号都是由系统内核产生
2.POSIX具体信号详解
首先确定几个概念;
什么是core文件?
具体参见我的另一篇博文:调试core文件详解
我的操作系统ubuntu14.04
vim /usr/include/x86_64-linux-gnu/bits/signum.h
/* Signals. */ #define SIGHUP 1 /* Hangup (POSIX). */ #define SIGINT 2 /* Interrupt (ANSI). */ #define SIGQUIT 3 /* Quit (POSIX). */ #define SIGILL 4 /* Illegal instruction (ANSI). */ #define SIGTRAP 5 /* Trace trap (POSIX). */ #define SIGABRT 6 /* Abort (ANSI). */ #define SIGIOT 6 /* IOT trap (4.2 BSD). */ #define SIGBUS 7 /* BUS error (4.2 BSD). */ #define SIGFPE 8 /* Floating-point exception (ANSI). */ #define SIGKILL 9 /* Kill,unblockable (POSIX). */ #define SIGUSR1 10 /* user-defined signal 1 (POSIX). */ #define SIGSEGV 11 /* Segmentation violation (ANSI). */ #define SIGUSR2 12 /* user-defined signal 2 (POSIX). */ #define SIGPIPE 13 /* broken pipe (POSIX). */ #define SIgalRM 14 /* Alarm clock (POSIX). */ #define SIGTERM 15 /* Termination (ANSI). */ #define SIGSTKFLT 16 /* Stack fault. */ #define SIGCLD SIGCHLD /* Same as SIGCHLD (System V). */ #define SIGCHLD 17 /* Child status has changed (POSIX). */ #define SIGCONT 18 /* Continue (POSIX). */ #define SIGSTOP 19 /* Stop,unblockable (POSIX). */ #define SIGTSTP 20 /* Keyboard stop (POSIX). */ #define SIGTTIN 21 /* Background read from tty (POSIX). */ #define SIGTTOU 22 /* Background write to tty (POSIX). */ #define SIGURG 23 /* Urgent condition on socket (4.2 BSD). */ #define SIGXcpu 24 /* cpu limit exceeded (4.2 BSD). */ #define SIGXFSZ 25 /* File size limit exceeded (4.2 BSD). */ #define SIGVTALRM 26 /* Virtual alarm clock (4.2 BSD). */ #define SIGPROF 27 /* Profiling alarm clock (4.2 BSD). */ #define SIGWINCH 28 /* Window size change (4.3 BSD,Sun). */ #define SIGPOLL SIGIO /* Pollable event occurred (System V). */ #define SIGIO 29 /* I/O Now possible (4.2 BSD). */ #define SIGPWR 30 /* Power failure restart (System V). */ #define SIGSYS 31 /* Bad system call. */ #define SIGUNUSED 31
查看系统中定义的信号列表 kill -l
sunxiaowu@sunxiaowu:~$ kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIgalRM 15) SIGTERM 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXcpu 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAX
常用信号说明:
截图来自unix高级环境编程(划红圈部分我们要重点掌握)
3.UNIX系统提供的signal信号函数
首先我们要明确:
在某个信号出现时,内核按照三种方式处理;
1.忽略此信号
2.捕捉信号
3.执行系统默认动作
#include <signal.h> typedef void (*sighandler_t)(int); sighandler_t signal(int signum,sighandler_t handler); //注意返回值的含义。若成功,则返回以前信号的处理配置,否则SIG_ERR
- func的值:SIG_IGN,SIG_DEL,函数调用地址
- 指定的函数地址所指函数为信号处理函数,调用此函数称为捕捉该信号
我们使用UNIX环境高级编程中的源码示例
在apue.3e中的signal模块下
~/Downloads/apue/apue.3e/signals$ vim sigusr.c #include "apue.h" static void sig_usr(int); /* one handler for both signals */ int main(void) { if (signal(SIGUSR1,sig_usr) == SIG_ERR) err_sys("can't catch SIGUSR1"); if (signal(SIGUSR2,sig_usr) == SIG_ERR) err_sys("can't catch SIGUSR2");if (signal(SIGTERM,sig_usr) == SIG_ERR) err_sys("can't catch SIGTERM");for ( ; ; )
pause();
}
static void sig_usr(int signo) /* argument is signal number */
{
if (signo == SIGUSR1)
printf("received SIGUSR1\n");
else if (signo == SIGUSR2)
printf("received SIGUSR2\n");
else if(signo == SIGTERM)
printf("received SIGTERM\n");
else
err_dump("received signal %d\n",signo);
}
sunxiaowu@sunxiaowu:~/Downloads/apue/apue.3e/signals$ ./sigusr & //后台启动进程
[3] 2977 //作业控制shell打印作业编号和进程id
sunxiaowu@sunxiaowu:~/Downloads/apue/apue.3e/signals$ kill -USR1 2977 //向该进程发送SIG_USR1
received SIGUSR1
sunxiaowu@sunxiaowu:~/Downloads/apue/apue.3e/signals$ kill -USR2 2977 //向该进程发送SIG_USR2
received SIGUSR2
sunxiaowu@sunxiaowu:~/Downloads/apue/apue.3e/signals$ kill 2977 //向该进程发送SIGTERM
received SIGTERM
注意:当一个进程调用fork时,其子进程继承父进程的信号处理方式。因为子进程在开始时复制了父进程内存映像,所以信号捕捉函数地址在子进程中也有意义。
4.中断的系统调用
- 当捕捉到某个信号时,被中断的是内核中执行的系统调用。系统调用分为两类:低系统调用(类似read这种可能阻塞的)和其他系统调用。低系统调用可能的常见情况
- 某些文件(网络通道,终端设备,磁盘文件,管道等)的数据不存在,则读操作可能会阻塞
- 如果数据不能被相同类型文件立即接收,则写操作可能会阻塞
- pause函数和wait waitpid(注意wait和waitpid在捕捉到信号时总是被中断)
- 某些ioctl操作
- 某些进程间通信函数
- 早期UNIX系统的特性(注意此处是早期的特性):如果进程在执行一个低速系统调用而阻塞期间捕捉到一个信号,则该系统调用就被中断不在继续执行。该系统调用返回出错,errno被设置为EINTR。
- 注意与磁盘I/O有关的系统调用(磁盘I/O又是一个可值得探讨的问题)。I/O操作总会很快返回,并使得调用者不在处于阻塞状态
- 中断系统调用方法的一个实例:一个进程启动了读终端操作,而使用该终端设备的用户却长时间离开该终端,进程就可能阻塞很久,这时我们可以发送信号,中断该read系统调用。
- 重点:对中断系统调用的错误返回处理。posix.1要求只有中断信号的SA_RESTART标志有效,才会开启重启系统调用的机制。(可以减少应用程序的负担)。或者由应用程序显示重启被中断的系统调用。
4.不可靠的信号和可靠的信号
不可靠的信号:指可能丢失的信号,一个信号产生了,但进程却可能一直不知道这点(早期的unix版本),后来对其修改,提供了可靠信号的机制。查看其他博主博客后,发现一篇详尽讲解,以下摘自博客(http://blog.csdn.net/u013074465/article/details/45978755)
“不可靠信号”
linux信号机制基本上是从Unix系统中继承过来的。早期Unix系统中的信号机制比较简单和原始,后来在实践中暴露出一些问题,因此,把那些建立在早期机制上的信号叫做"不可靠信号",信号值小于SIGRTMIN(Red hat 7.2中,SIGRTMIN=32,SIGRTMAX=63)的信号都是不可靠信号。
这就是"不可靠信号"的来源。它的主要问题是:
- 进程每次处理信号后,就将对信号的响应设置为默认动作。在某些情况下,将导致对信号的错误处理;因此,用户如果不希望这样的操作,那么就要在信号处理函数结尾再一次调用signal(),重新安装该信号。
- 信号可能丢失,后面将对此详细阐述。 如果在进程对某个信号进行处理时,这个信号发生多次,对后到来的这类信号不排队,那么仅传送该信号一次,即发生了信号丢失。
因此,早期unix下的不可靠信号主要指的是进程可能对信号做出错误的反应以及信号可能丢失。
Linux支持不可靠信号,但是对不可靠信号机制做了改进:在调用完信号处理函数后,不必重新调用该信号的安装函数(信号安装函数是在可靠机制上的实现)。因此,Linux下的不可靠信号问题主要指的是信号可能丢失。
"可靠信号"
随着时间的发展,实践证明了有必要对信号的原始机制加以改进和扩充。所以,后来出现的各种Unix版本分别在这方面进行了研究,力图实现"可靠信号"。由于原来定义的信号已有许多应用,不好再做改动,最终只好又新增加了一些信号,并在一开始就把它们定义为可靠信号,这些信号支持排队,不会丢失。同时,信号的发送和安装也出现了新版本:信号发送函数sigqueue()及信号安装函数sigaction()。POSIX.4对可靠信号机制做了标准化。但是,POSIX只对可靠信号机制应具有的功能以及信号机制的对外接口做了标准化,对信号机制的实现没有作具体的规定。
信号值位于SIGRTMIN和SIGRTMAX之间的信号都是可靠信号,可靠信号克服了信号可能丢失的问题。Linux在支持新版本的信号安装函数sigation()以及信号发送函数sigqueue()的同时,仍然支持早期的signal()信号安装函数,支持信号发送函数kill()。
注:不要有这样的误解:由sigqueue()发送、sigaction安装的信号就是可靠的。事实上,可靠信号是指后来添加的新信号(信号值位于SIGRTMIN及SIGRTMAX之间);不可靠信号是信号值小于SIGRTMIN的信号。信号的可靠与不可靠只与信号值有关,与信号的发送及安装函数无关。目前linux中的signal()是通过sigation()函数实现的,因此,即使通过signal()安装的信号,在信号处理函数的结尾也不必再调用一次信号安装函数。同时,由signal()安装的实时信号支持排队,同样不会丢失。
对于目前linux的两个信号安装函数:signal()及sigaction()来说,它们都不能把SIGRTMIN以前的信号变成可靠信号(都不支持排队,仍有可能丢失,仍然是不可靠信号),而且对SIGRTMIN以后的信号都支持排队。这两个函数的最大区别在于,经过sigaction安装的信号都能传递信息给信号处理函数(对所有信号这一点都成立),而经过signal安装的信号却不能向信号处理函数传递信息。对于信号发送函数来说也是一样的。
可靠信号术语:
- 当造成信号的事件发生时,我们称 为进程产生一个信号
- 当一个信号产生时,内核通常在进程表中以某种形式设置一个标志
- 当对进程表设置了某种标志时,我们称为向进程递送了一个信号
在两者之间的的时间间隔之内,称信号是为未决的(pending)
- 进程可以采取一种“阻塞信号递送”的机制,每个进程都有一个信号屏蔽字,它规定了当前要阻塞递送到该进程的信号集。可以调用sigprocmask来检测和更改当前信号屏蔽字
- 如果为进程产生了一个阻塞的信号,且对该信号的动作不是忽略,则为该进程将此信号保持为未决状态,直至该进程解除了对此信号的阻塞,或者将对此信号的动作更改为忽略,而后递送信号
- 内核在递送一个原来被阻塞的信号给进程时,才决定对它的处理方式
- 进程调用sigpending函数来判定哪些信号处于阻塞并处于未决状态。
- 如果在进程解除对谋个信号的阻塞之前,这种信号发生了多次,posix.1 允许该系统递送该信号一次或者多次。
- POSIX.1定义了一个新数据类型sigset_t来表示信号集。
5.可重入函数
参见我的另一篇博客:可重入函数讲解
6.信号机制常用实例说明
32547 unix编程
32547
Faculty of Engineering and Information Technology
Subject 32547 UNIX Systems Programming, Spring 2021
Assignment
Description
This assignment is an individual programming assignment using Python. It addresses objectives 2
and 3 as listed in the Subject Outline document.
No limits apply to the number of lines of code of the program.
Assignments are to be completed individually (this might be checked with the use of anti‐
plagiarism tools such as Turnitin). You should not receive help in the preparation of this
assignment, nor ask anyone else to prepare it on your behalf in any way.
Marks
The assignment corresponds to 30% of the total marks.
Submission
The completed assignment is due by 5:00pm of Friday 29 October 2021.
PLEASE PAY ATTENTION TO THE FOLLOWING SUBMISSION INSTRUCTIONS:
- Your Python program has to be submitted on Canvas, following the “Assignments” menu
and then the “Assignment” link by the due date. You can prepare your Python program
anywhere you like, but probably the easiest option is to develop it in Ed STEM. - Please submit only your Python program, and nothing else (no data files).
- Late submissions will be deducted one mark per day late; more than seven days late, the
assignment will receive zero. Special considerations for a late submission must be
arranged in advance with the Subject Coordinator.
2
Academic Standards
The assignments in this Subject should be your own original work. Any code taken from a
textbook, journal, the Internet or any other source should be acknowledged. For referencing,
please use the standard referencing conventions (http://www.lib.uts.edu.au/hel...).
Marking Scheme
Mark Range - All requirements of the assignment are met. The submitted
program can be executed by the lecturer “as is” and produces the
requested output.
24‐29 The program works correctly with any valid file and for all options,
but its execution experiences some minor problems.
18‐23 The program does not work as expected with one of the options.
0‐17 This range goes from no submission at all (0 marks) to a submission
which does not meet major requirements of the assignment.
Examples:
the program does not work as expected with two or more
options;
the program generates unhandled errors;
the program does not solve the assignment problem.
The assignments will be marked within two weeks from the submission deadline or as soon as
possible.
Important notes:
Submission of this assignment is not compulsory to pass the subject; do not feel that you
have to submit it “at all costs” and perhaps be tempted to seek unauthorised assistance.
There are no minimum requirements on the marks on this assignment to pass the subject.
This assignment must be your own work and you should not be helped by anyone to prepare
it in any way; your assignment may be tested with anti‐plagiarism software that detects
superficial changes such as changing variable names, swapping lines of code and the like.
The subject coordinator may ask you to describe your assignment in a “viva voce” in Zoom to
finalise your mark.
Understanding the assignment specifications is part of the assignment itself and no further
instructions will be provided; on the other hand, whatever is not constrained you can
implement it according to your own best judgment.
3
Title: Partition information with Python
In this assignment, you will use Python for writing a program that can report information about
the partitions of a Unix system. The program will read a pseudo system file containing partition
data and will report the requested information to the user.
These are the specifications for your Python program: - It must be named partitionreport.py
- It must be invoked as:
python partitionreport.py option partition_file
The program must check that argument partition_file exists, is a file and is readable. If not,
it must print a message of your choice to the standard output and exit. The specifications
for the partition_file and option arguments are given below. - File partition_file can have any arbitrary name (including the extension). It must be a file of
text with the following format:
a. The file consists of an arbitrary number of lines (including, possibly, zero lines).
Each line corresponds to a partition.
b. Each line must contain six fields separated by a space character.
c. The six fields are: partition, mount point, file system type, permissions, total space
and used space.
d. Fields partition and mount point are standard Unix absolute filenames.
e. Field file system type is a string (of maximum 10 characters). The characters
allowed include lowercase letters, uppercase letters, digits, the underscore (_) and
the hyphen (‐).
f. Field permissions can be either string ''rw'' or string ''ro''.
g. Fields total space and used space are positive integers represented as strings of no
more than 10 digits each.
The following example is the reference specification for the format of file partition_file:
/dev/sdb1 / ext3 rw 10317828 4439828
/dev/sda1 /home ext3 rw 2885780 2265324
/dev/sdb2 /usr nfs rw 20635656 446188
/dev/sdc1 /var ext4 rw 2885780 2265324
/dev/sr0 /cdrom iso9660 ro 45684 45684
Fundamental note: your program is not expected to verify that file partition_file complies
with the above specifications. It will only be tested with compliant files.
4 - Your program can be invoked with option: ‐f. In this case, it must print the names of all the
unique file system types in use, in the order in which they first appear in file partition_file,
preceded by string ''File system types in use: '' and separated by a space
character.
Example with the example partition_file given above:
Command line:
python partitionreport.py –f partition_file
Output:
File system types in use: ext3 nfs etx4 iso9660
In the case in which file partition_file is empty, your program will print:
No file system types found in argument file - Your program can be invoked with option: ‐a. In this case, it must print the following string:
Overall space available in read-write partitions: <the overall space
available in "rw" partitions in file partition_file, including, possibly, zero>
The space available in a partition is computed as the difference between the total space
and used space fields. The overall space available in read‐write partitions is computed as
the sum of the space available in every read‐write partition.
Example with the example partition_file given above:
Command line:
python partitionreport.py -a partition_file
Output:
Overall space available in read-write partitions: 27308380 - Your program can be invoked with option: ‐p partition. The format of string partition is the
same as the partition field in file partition_file (i.e. a standard Unix absolute filename). In
this case, your program must print the following string:
Partition partition is <read-write or read-only> and has <space available>
available space
Example with the example partition_file given above:
Command line:
python partitionreport.py –p /dev/sdb1 partition_file
Output:
Partition /dev/sdb1 is read-write and has 5878000 available space
5
In the case in which file partition_file does not contain the requested partition (including
the case where the file is empty), your program must print:
Partition not found - Your program can be invoked with option: ‐v. In this case, it must only print your name,
surname, student ID and date of completion of your assignment, in a format of your choice.
Please note that argument partition_file is still required. - No options can be used simultaneously. This meansthat your program must only be invoked
with one of the options at a time. - If your program is invoked with any other syntax than those specified above, it must print a
message of your choice to the standard output and exit.
Examples of incorrect syntax:
python partitionreport.py -Z partition_file (i.e., wrong option)
python partitionreport.py -a (i.e., missing the argument file)
python partitionreport.py -p partition_file (i.e., missing the partition
argument)
WX:codehelp
c – POSIX信号行为
如果SIGSTOP排队,是否有任何方法可以从该进程外部将其从队列中删除,例如在跟踪过程中?
解决方法
The signals SIGKILL and SIGSTOP cannot be caught,blocked,or ignored.
一个简单的测试,应用程序在断点处停止并向其发送SIGSTOP,显示gdb在我点击“下一个”时显示一些信息.信号显然已传递给应用程序.在我发送SIGCONT之前,它无法继续调试.
(gdb) next Program received signal SIGSTOP,Stopped (signal). fill (arr=0x7fffffffdff0,size=5) at tmp.cpp:28 (gdb) next Program received signal SIGCONT,Continued. fill (arr=0x7fffffffdff0,size=5) at tmp.cpp:28 (gdb) next (gdb)
c – posix信号量的Sys V SEM_UNDO等价物
解决方法
// set handler signal(SIGSEGV,handler); void handler(int signum) { // unlock the locked semaphores signal(SIGSEGV,SIG_DFL); }
c – 在类中初始化静态POSIX信号量
class Semaphore { private: static sem_t sem_id; }
在cpp:
sem_init(&Semaphore::sem_id,0);
显然,编译器不会让我在函数之外运行代码.但它不是一种可以初始化为值的类型.我该怎么做?
解决方法
遗憾的是,sem_t不是一个类,所以你不能继承它,而必须改为组成它:
#include <semaphore.h> class scoped_sem_t { public: scoped_sem_t() { sem_init(&sem,0); } ~scoped_sem_t() { sem_destroy(&sem); } sem_t& get() { return sem; } private: sem_t sem; }; class Semaphore { private: static scoped_sem_t impl; // use Semaphore::impl.get() }; scoped_sem_t Semaphore::impl; // (don't forget this!)
(N.B.完全未经测试,但我想它应该有用……)
(另外,不是类设计的最好例子,但给你的要点.)
否则,遗憾的是,没有办法整齐地做到这一点.您可以在main的开头编写sem_init,但要注意不要从任何其他静态初始化器引用Semaphore :: sem_id.
今天关于UNIX编程专题-POSIX信号和unix 信号量的介绍到此结束,谢谢您的阅读,有关32547 unix编程、c – POSIX信号行为、c – posix信号量的Sys V SEM_UNDO等价物、c – 在类中初始化静态POSIX信号量等更多相关知识的信息可以在本站进行查询。
本文标签: