GNU FORK PTHREAD SIGNALS
Linux程序设计入门 - fork, pthread, and signals
在UNIX程序设计中,学会fork及signal的运用,算是相当基本的功夫。
fork()及signal经常运用在daemon守护神这一类常驻程序,另外像
a4c.tty/yact/chdrv这些中文终端机程序也有用到,一般如
Mozilla/Apache/Squid等大程序几乎都一定会用到。
虽然在UNIX下的程序写作,对thread的功能需求并非很大,但thread在现代的
作业系统中,几乎都已经存在了。pthread是Linux上的thread函数库,如果您
要在Linux下撰写多线程序,例如MP3播放程序,熟悉pthread的用法是必要的。
pthread及signal都可以用一大章来讨论。在这里,我只谈及最简单及常用的技
巧,当您熟悉这些基本技巧的运用後,再找一些专门深入探讨pthread及signal
程序写作的书籍来研究。这些进阶的写法,用到的机会较少,将层次分明,学
习速度应该会比较快。
程序分歧fork()
fork()会产生一个与父程序相同的子程序,唯一不同之处在於其process
id(pid)。
如果我们要撰写守护神程序,或是例如网路伺服器,需要多个行程来同时提供
多个连线,可以利用fork()来产生多个相同的行程。
函数宣告
pid_t fork(void);
pid_t vfork(void);
返回值:
-1 : 失败。
0 : 子程序。
>0 : 将子程序的process id传回给父程序。
在Linux下fork()及vfork()是相同的东西。
范例一: fork.c
在这个范例中,我们示范fork()的标准用法。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void main(void)
{
pid_t pid;
printf("hello\n");
pid = fork();
switch (pid) {
case -1: printf("failure!\n"); break;
case 0: printf("I am child!\n"); break;
default: printf("my child is %d\n",pid); break;
}
for (;;) { /* do something here */ }
}
编译:
gcc -o ex1 fork.c
执行结果:
./ex1 &
hello
my child is 8650
I am child!
我们可以见到,使用fork(),可将一个程序分岐成两个。在分歧之前的程序码
只执行一次。
检验行程:
ps | grep ex1
8649 p0 R 0:40 ./ex1
8650 p0 R 0:40 ./ex1
8649是父程序的pid,8650则为子程序的pid。
您会需要用到"killall ex1"来杀掉两个行程。
范例二: daemon.c
在UNIX中,我们一般都利用fork(),来实作所谓的"守护神程序",也就是DOS中
所谓的"常驻程序"。一般的技巧是将父程序结束,而子程序便成为"守护神"。
这个范例中,示范一般标准的daemon写法。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void main(void)
{
pid_t pid;
pid = fork();
if (pid>0) {
printf("daemon on duty!\n");
exit(0);
} else
if (pid<0) {
printf("Can't fork!\n");
exit(-1);
}
for (;;) {
printf("I am the daemon!\n");
sleep(3);
/* do something your own here */
}
}
编译:
gcc -o ex2 daemon.c
执行结果:
./ex2
daemon on duty!
I am the daemon!
接下来每三秒钟,都会出现一个"I am the daemon!"的讯息,这表示您的程序
已经"长驻"在系统中了。
检验行程:
ps | grep ex2
8753 p0 S 0:00 ./ex2
注意到在范例一中,我们下的指令为"./ex1 &",而在范例二中为"./ex2",没
有"&"符号。
范例三: lock.c
许多的时候,我们希望"守护神"在系统中只有一个,这时候会需要用到pid
lock的技巧。如果您注意到/var/run目录中的内容,您会发现到有许多的*.pid
档,观看其内容都是一些数字,这些数字其实就是该行程的pid。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void main(void)
{
FILE *fp;
pid_t pid;
exit(-1);
}
act.sa_handler = quit;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
sigaction(SIGTERM,&act,NULL);
sigaction(SIGHUP,&act,NULL);
sigaction(SIGINT,&act,NULL);
sigaction(SIGQUIT,&act,NULL);
sigaction(SIGUSR1,&act,NULL);
sigaction(SIGUSR2,&act,NULL);
for (;;) {
sleep(3);
}
}
编译:
gcc -o ex1 lock.c
执行
./ex1
daemon on duty!
送信号
我们先找出该守护神程序的pid
PID=`cat /var/run/lock.pid`
接下来利用kill来送信号
kill $PID
Receive signal 15
程序将会结束,并且/var/run/lock.pid将会被删除掉,以便下一次daemon再启
动。注意到如果quit函数内,没有放exit(),程序 将永远杀不掉。
接下来送一些其它的信号试试看。
./ex1
PID=`cat /var/run/lock.pid`
kill -HUP $PID
Receive signal 1
您可以自行试试
kill -INT $PID
kill -QUIT $PID
kill -ILL $PID
.
.
.
等等这些信号,看看他们的结果如何。
信号的定义
在/usr/include/signum.h中有各种信号的定义
#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 /* ??? */
#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 SIGUNUSED 31
函数宣告:
Signal Operators
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);
Signal Handling Functions
int sigaction(int signum, const struct sigaction *act,struct
sigaction *oldact);
int sigprocmask(int how, const sigset_t *set, sigset_t
*oldset);
int sigpending(sigset_t *set);
int sigsuspend(const sigset_t *mask);
Structure Signal Action
struct sigaction {
void (*sa_handler)(int);
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer)(void);
}
OK STATION, Webmaster, Brian Lin
GNU FORK PTHREAD SIGNALS的更多相关文章
- Cross-platform Tools
MinGW和Cygwin都解决了C++跨平台交叉编译的问题,使Linux下的程序在Windows上编译运行成为可能. MinGW给习惯在Linux上开发的人员在windows上提供了一套类似的工具集: ...
- cygwin-介绍-安装
初学linux时,最头疼的是,因为windows和linux各有优点,各有用途,所以只能麻烦的在两者之间切换,不断的重启.开机时也麻烦,因为初学者大多数使用windows,装了linux后,开机会自动 ...
- [cross compile]cygwin和mingw
转自:http://blog.csdn.net/embededvc/article/details/6829010 1. MinGW和CygWin/gcc概念 Unix下编译通过的C代码,在win32 ...
- mingw64环境搭建
转自:http://www.cr173.com/soft/132367.html MinGW64位版,默认编译出来是64位的,需要编译32位请使用-m32 参数!mingw是一款gnu工具集合是Min ...
- Android学习之一:Cygwin简介
为了能够一窥Android底层的东东,还是要搭建编译Android的环境.虽有Ubuntu和Suse系统,无奈总感觉在不同的系统下切来切去很是不便.在Windows工作学习,要编译Android,就不 ...
- win7 下使用cygwin
http://cygwin.com/index.html 还是看官网! 很多用windows的朋友不习惯于用linux的开发环境.虽然很乐意尝试一下,但是往往怕 linux系统打乱了自己的正 ...
- cygwin,在win中开发linux程序
cygwin,在win中开发linux程序 http://www.cygwin.cn/site/info/show.php?IID=1001 很多用windows的朋友不习惯于用linux的开发环境 ...
- Cygwin、MinG、MSys区别与联系(转)
转自:https://www.biaodianfu.com/cygwin-ming-msys.html 什么是Cygwin? Cygwin,原Cygnus出品(已被红帽收购),目前是RedHat名下的 ...
- Cygwin使用2-心得
引用:http://www.jb51.net/article/6236.htm 1.在cygwin里访问Windows盘 cd /cygdrive/c cd c: 2.整合cygwin命令到Windo ...
随机推荐
- 【设计模式 - 8】之组合模式(Composite)
1 模式简介 组合模式可以将对象以树形结构来表现"整体/部分"层次结构,让客户以一致的方式处理个别形象以及对象组合. 组合模式让我们能用树形方式创建对象的结构,树里面包含 ...
- mac下修改mysql的默认字符集为utf8
1,检查默认安装的mysql的字符集 mysql> show variables like '%char%'; +--------------------------+------------- ...
- 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(29)-T4模版
原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(29)-T4模版 这讲适合所有的MVC程序 很荣幸,我们的系统有了体验的地址了.演示地址 之前我们发布了一 ...
- 关于Win8对getElementsByTagName等dom方法兼容性的替代方法
在对Twebbrowser进行dom编程时,引用MSHTML并使用其中的HTMLDocument; IHTMLElementCollection;IHTMLElement;能获得较好的代码提示 其中封 ...
- 在LaTeX里插入全页的pdf 分类: LaTex 2015-02-04 17:20 142人阅读 评论(0) 收藏
要帮女友排版毕业论文,需要插入封面,省时省力的方法就是把学校给的Word封面保存成PDF然后插入到Latex文档中. 首先添加下面的宏: \usepackage[final]{pdfpages} 然后 ...
- COMPACT 行记录格式
CREATE TABLE `mytest` ( `t1` varchar() DEFAULT NULL, `t2` varchar() DEFAULT NULL, `t3` ) DEFAULT NUL ...
- [转]Flex 布局教程:语法篇
网页布局(layout)是CSS的一个重点应用. 布局的传统解决方案,基于盒状模型,依赖 display属性 + position属性 + float属性.它对于那些特殊布局非常不方便,比如,垂直居中 ...
- 【Android】碎片Fragment
1.碎片可以让界面在平板上更好地展示. 2.碎片是一种可以嵌入到活动中的UI片段,它能让程序更加合理和充分地利用一个大屏幕的空间.有自己的生命周期,能包含布局. 3.新建碎片类继承Fragment,可 ...
- c++矩阵运算
优化了一些算法 #pragma once #include <iostream> #include <iomanip> #include <string> #def ...
- jQuery作用
jquery是前端里面比较总要的,是很强大的一个选择器. 表单: 1.$(":input") 查找所有的input元素 2.$("text") 匹配所有的 ...