上过操作系统这门课,所以略知进程与信号的概念,当时进程学的还好些,毕竟xp下的进程,我们经常触及;可对于信号,我真晕了,什么wait(),signal()的...直到今天真正在linux下写写代码,才使我找到信号的真谛~尽管尝试的应用很简单,不过真的有所得!
1 信号
先回忆下信号的 概念:信号是为了使进程获得某项重要通知而发送给它的重要事件。这时进程必须立即停止当前的工作,转而处理该信号。每一个信号都用一个整数代表信号的类型。
ps:这些信号定义在/usr/include/asm-i386/signal.h中,不过现在有的定义好的信号也不知道用处,希望知道的人能给些提示.
键盘可以发送下列信号:
Ctrl-C: 发送 SIGINT, 缺省情况下,进程立即终止
Ctrl-Z: 发送SIGTSTP,缺省情况下,进程被挂起
Ctrl-/: 发送SIGABRT,缺省情况下,进程立即中止,类似于Ctrl-C,但是有更强灵活性
当在终端输入fg命令时可以重新激活挂起的进程,它发送SIGCONT信号
上述我们可得键盘可以发送信号,若想改变其缺省状态,我们可以编写函数void catch_int(int sig_num),然后在main函数中调用signal(SIGINT, catch_int)
代码如下:
#include
<
stdio.h
>
#include
<
unistd.h
>
#include
<
signal.h
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
void
catch_int(
int
sig_num )
{
//reset SIGINT, catch_int
signal( SIGINT, catch_int );
printf( "Control-C is ignored, please don't waste time.%d ", sig_num);
fflush( stdout );
//在多进程时常常用到fflush();
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
int
main(
int
argc,
char
*
argv[ ] )
{
printf( "Want to try control-C? " );
signal( SIGINT, catch_int );
//catch_int(SIGINT);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
//into while
while( 1 )
pause( );
return 0;
}
2 应用信号做timeout
SIGALRM是定时的信号
#include
<
stdio.h
>
#include
<
unistd.h
>
#include
<
signal.h
>
#include
<
stdlib.h
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
void
catch_alarm(
int
sig_num )
{
printf( " Sorry, time limit reached. " );
alarm( 0 );
exit( 0 );
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
int
main(
int
argc,
char
*
argv[ ] )
{
printf( "Your username( 5 second limit ): " );
fflush( stdout );
signal( SIGALRM, catch_alarm ); //设置当有SIGALRM信号时操作,模认为输出ALARM xxx后退出程序
alarm( 5 );
char *a;
fgets( a, 40, stdin ); //从stdin中取用户输入的用户名
printf( "Your username is: %s ", a );
return 0;
}
3 进程与信号
进程概念: 执行一个代码段,有自己的堆栈和内存页面的实体
fork()命令建立信进程,与普通函数不同的是他的返回有两次。fork()把当前的进程分为两个进程,一个父进程和一个子进程。原来进程的所有内存页面在fork时分为相同的两份,所以子进程与父进程都是用相同的映射。在父进程中,它的返回值是子进程的进程号;在子进程中,它的返回值是0;错误返回-1。
因此如果我们写如下函数:
if(fork() = =0)
{
printf(“This is the child process/n”);
}else{
printf(“This is the parent process/n”);
}
输出结果显示为
This is the child process
This is the parent process
呵呵,很令人奇怪吧....if & else 均中标...
说完fork(),接下来恼人的是wait()函数。 wait()会暂时停止目前进程的执行,直到有信号来到或子进程结束。当子进程退出时,实际上它的状态处于zombie,只有当父进程调用wait()确认后,子进程才会真正意义上kill。反过来当父进程先退出时,子进程会继续进行。
实例代码如下:
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
int main( int argc, char *argv[ ] )
{
pid_t child_pid;
int child_status;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
child_pid = fork( );
switch( child_pid ){
case -1:
perror( "fork" );
exit( 1 );
case 0: //中标
printf( "child: hello from child process " );
sleep( 5 );
exit( 0 );
default: //中标
printf( "parent: I am waiting child process " );
wait( &child_status ); //父进程会无所事事
}
return 0;
}
我们为了解决wait()给父进程带来的无所事事,我们用信号量来解决
当子进程结束时,会发送SIGCHLD信号到父进程,所以我们获取此信号再加些操作就可以起到解决问题的目的啦~~
#include
<
stdio.h
>
#include
<
unistd.h
>
#include
<
sys
/
types.h
>
#include
<
sys
/
wait.h
>
#include
<
signal.h
>
#include
<
stdlib.h
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
void
signal_handler(
int
n )
{
int child_status;
wait( &child_status );
printf( "child exited. " );
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
int
main(
int
argc,
char
*
argv[ ] )
{
pid_t child_pid;
int child_status;
signal( SIGCHLD, signal_handler ); //when child process exit( the status of zombie ) 获取SIGCHLD信号
child_pid = fork( );
int i=0;
switch( child_pid ){
case -1:
perror( "fork" );
exit( 1 );
case 0:
printf( "child: hello from child process " );
sleep( 3 ); //我就不退出,看父进程傻等我不 ^_^
exit( 0 );
default:
for( i;i<10;i++ ){
printf( "%d", i ); //会连续输出
fflush( stdout ); //不写的话会有bug
sleep( 1 );
}
}
return 0;
}
OK,今天进行到此~~
不过父进程子进程还是不能交互,等明天或者过两天,管道研究
至于进程与进程的交互,就要用到消息了吧...
继续学习...
1 信号
先回忆下信号的 概念:信号是为了使进程获得某项重要通知而发送给它的重要事件。这时进程必须立即停止当前的工作,转而处理该信号。每一个信号都用一个整数代表信号的类型。
ps:这些信号定义在/usr/include/asm-i386/signal.h中,不过现在有的定义好的信号也不知道用处,希望知道的人能给些提示.
键盘可以发送下列信号:
Ctrl-C: 发送 SIGINT, 缺省情况下,进程立即终止
Ctrl-Z: 发送SIGTSTP,缺省情况下,进程被挂起
Ctrl-/: 发送SIGABRT,缺省情况下,进程立即中止,类似于Ctrl-C,但是有更强灵活性
当在终端输入fg命令时可以重新激活挂起的进程,它发送SIGCONT信号
上述我们可得键盘可以发送信号,若想改变其缺省状态,我们可以编写函数void catch_int(int sig_num),然后在main函数中调用signal(SIGINT, catch_int)
代码如下:
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
2 应用信号做timeout
SIGALRM是定时的信号
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
3 进程与信号
进程概念: 执行一个代码段,有自己的堆栈和内存页面的实体
fork()命令建立信进程,与普通函数不同的是他的返回有两次。fork()把当前的进程分为两个进程,一个父进程和一个子进程。原来进程的所有内存页面在fork时分为相同的两份,所以子进程与父进程都是用相同的映射。在父进程中,它的返回值是子进程的进程号;在子进程中,它的返回值是0;错误返回-1。
因此如果我们写如下函数:
if(fork() = =0)
{
printf(“This is the child process/n”);
}else{
printf(“This is the parent process/n”);
}
输出结果显示为
This is the child process
This is the parent process
呵呵,很令人奇怪吧....if & else 均中标...
说完fork(),接下来恼人的是wait()函数。 wait()会暂时停止目前进程的执行,直到有信号来到或子进程结束。当子进程退出时,实际上它的状态处于zombie,只有当父进程调用wait()确认后,子进程才会真正意义上kill。反过来当父进程先退出时,子进程会继续进行。
实例代码如下:
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/717446ca04a6125dc5b6b54e0fa14ab4.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
我们为了解决wait()给父进程带来的无所事事,我们用信号量来解决
当子进程结束时,会发送SIGCHLD信号到父进程,所以我们获取此信号再加些操作就可以起到解决问题的目的啦~~
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/717446ca04a6125dc5b6b54e0fa14ab4.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/717446ca04a6125dc5b6b54e0fa14ab4.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
OK,今天进行到此~~
不过父进程子进程还是不能交互,等明天或者过两天,管道研究
至于进程与进程的交互,就要用到消息了吧...
继续学习...