尝试linux下c编程之进程与信号
来源:互联网 发布:免费qq机器人软件 编辑:程序博客网 时间:2024/06/06 07:46
上过操作系统这门课,所以略知进程与信号的概念,当时进程学的还好些,毕竟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)
代码如下:
2 应用信号做timeout
SIGALRM是定时的信号
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。反过来当父进程先退出时,子进程会继续进行。
实例代码如下:
我们为了解决wait()给父进程带来的无所事事,我们用信号量来解决
当子进程结束时,会发送SIGCHLD信号到父进程,所以我们获取此信号再加些操作就可以起到解决问题的目的啦~~
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)
代码如下:
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
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();
}
int main( int argc, char* argv[ ] )
{
printf( "Want to try control-C? " );
signal( SIGINT, catch_int );
//catch_int(SIGINT);
//into while
while( 1 )
pause( );
return 0;
}
#include <unistd.h>
#include <signal.h>
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();
}
int main( int argc, char* argv[ ] )
{
printf( "Want to try control-C? " );
signal( SIGINT, catch_int );
//catch_int(SIGINT);
//into while
while( 1 )
pause( );
return 0;
}
2 应用信号做timeout
SIGALRM是定时的信号
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
void catch_alarm( int sig_num )
{
printf( " Sorry, time limit reached. " );
alarm( 0 );
exit( 0 );
}
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;
}
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
void catch_alarm( int sig_num )
{
printf( " Sorry, time limit reached. " );
alarm( 0 );
exit( 0 );
}
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>
int main( int argc, char *argv[ ] )
{
pid_t child_pid;
int child_status;
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;
}
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
int main( int argc, char *argv[ ] )
{
pid_t child_pid;
int child_status;
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>
void signal_handler( int n )
{
int child_status;
wait( &child_status );
printf( "child exited. " );
}
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;
}
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdlib.h>
void signal_handler( int n )
{
int child_status;
wait( &child_status );
printf( "child exited. " );
}
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,今天进行到此~~
不过父进程子进程还是不能交互,等明天或者过两天,管道研究
至于进程与进程的交互,就要用到消息了吧...
继续学习...
- 尝试linux下c编程之进程与信号
- linux下c编程进程通信-管道与信号
- 尝试linux下c编程之管道
- 尝试linux下c编程之Popen()
- Linux下的C编程入门之进程控制与进程通信编程
- linux基础编程:进程通信之信号
- Linux C编程之信号介绍
- linux 系统编程 之信号 test10_1.c
- linux 系统编程之信号 test10_2.c
- linux 系统编程 之信号 test10_3.c
- linux 系统编程之信号 test10_4.c
- linux系统编程之信号 test10_5.c
- linux系统编程之 信号 test10_6.c
- linux系统编程之信号 test10_7.c
- linux系统编程之信号 test10_8.c
- linux系统编程之信号 test10_9.c
- linux系统编程之信号 test10_10.c
- Linux 进程与信号
- 美警方调查“一夫多妻”宗教组织
- aaaaaaaaaaaaaaaaaaaaaaaaaa
- Net程序如何防止被注入整站通用
- gridview改变鼠标指定行背影色
- 配置jsp 环境(eclipse+myeclipse+tomcat)
- 尝试linux下c编程之进程与信号
- Code Complete 读书笔记(Chapter 14 Organizing Straight-line Code)
- grails的基本配置和中文编码注意事项
- Find Nth maximum value in SQL Server
- 三个天才的内心世界
- C/C++的左值和右值(转载自 水木社区 )
- 3G手机和一般手机有什么不同?
- [转贴]ASP.Net MVC框架配置与分析
- MRTG FOR WINDOWS 安装指南