//第一个进程实例
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main( )
{
pid_t myPid;
pid_t myParentPid;
gid_t myGid;
uid_t myUid;
myPid=getpid( );
myParentPid=getppid( );
myGid=getgid( );
myUid=getuid( );
printf( "my process id is %d/n",myPid );
printf( "my parent's process id is %d/n",myParentPid );
printf( "my user id is %d/n",myUid );
printf( "my group id is %d/n",myGid );
return 0;
}
//调用fork的应用实例
/*
注意fork首先把CPU的控制权交给子进程。
fork的返回值:
On success, the PID of the child process is returned in the parent,
and 0 is returned in the child. On failure, -1 is returned in the parent,
no child process is created, and errno is set appropriately.
*/
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <string.h>
#include <sys/wait.h>
int main( )
{
pid_t ret;
int status,i;
int role=-1;
ret=fork( );
if( ret==0 ) //child process
{
printf( "Child:this is the child process ( pid %d )/n",getpid( ) );
for( i=0;i<6;++i )
{
printf( "Child: at count %d /n ",i );
sleep( 1 );
}
role=1;
}
else if( ret>0 ) //parent process ,ret is the child process's pid
{
printf( "Parent:this is the parent process ( pid %d )/n",getpid( ) );
for( i=0;i<6;++i )
{
printf( "Parent: at count %d /n ",i );
sleep( 1 );
}
wait( &status );
role=0;
}
else
{
printf( "Parent:Error trying to fork( )( %s )/n",strerror(errno));
}
printf ( "%s:Exiting.../n",( (role==0)?"Parent":"Child" ) ); //both parent and child process execute
return 0;
}
/*信号,即GUN/Linux中进程的回调符号。可以为某个进程注册为在某事件发生时接受信号或
是在某个默认操作退出时忽略信号。
*/
//为捕获信号注册句柄实例
#include <stdio.h>
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
void catch_ctlc( int sig_num )
{
printf( "/nCaught Ctrl+C/n" );
fflush( stdout );
return; //可有可无
}
int main( )
{
//查看系统信号列表:man 7 signal
signal( SIGINT,catch_ctlc );
printf( "Go ahead,make my day/n" );
//pause()causes the calling process (or thread) to sleep until a signal is delivered
pause( );
return 0;
}
/************发出信号****************/
/*
kill()可以向任意一个具有相应权限的进程发送信号并发挥作用;
raise( sig )可以向自身进程发送信号
*/
//从子进程向父进程发出一个信号
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
void usr1_handler( int sig_num )
{
printf( "Parent ( %d ) got the SIGUSR1/n",getpid( ) );
}
int main( )
{
pid_t ret;
int status;
int role=-1;
ret=fork( );
if( ret>0 )
{
printf( "Parent:this is the parent process ( pid %d )/n",getpid( ) );
signal( SIGUSR1,usr1_handler );
role=0;
pause( );
printf( "Parent:waiting for child exit/n" );
ret=wait( &status );
}
else if( ret==0 )
{
printf( "Child:this is the child process ( pid %d )/n",getpid( ) );
role=1;
sleep( 1 ); //注意,当程序中出现sleep()的时候,就要注意对输出产生的滞后影响
printf( "Child:Sending SIGUSR1 to pid %d/n",getppid( ) ); //此处的‘/n’不仅有换行的作用,还有刷新stdout的作用
//kill(pid,signal)可用于向某个进程发送信号
kill( getppid( ),SIGUSR1 );
sleep( 2 );
}
else
{
printf( "Parent:Error trying to fork( )( %s )/n",strerror(errno));
}
printf("/n%s:Exiting.../n",( (role==0)?"Parent":"Child" ));
return 0;
}
/*这个例子中父子进程都没有发送SIGUSR1信号
这个例子可用于展示进程间进行异步通讯的有力方法
./test &
kill -s 10 -p parent'pid // 10 represent SIGUSR1
kill -s SIGUSR1 -p child'pid
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>
#include <error.h>
void usr1_handler( int sig_num )
{
printf( "Process ( %d ) got the SIGUSR1/n",getpid( ) );
}
int main( )
{
pid_t ret;
int status;
int role=-1;
signal( SIGUSR1,usr1_handler );
ret=fork( );
if( ret>0 )
{
printf("This is parent process ( pid %d )/n",getpid( ));
role=0;
printf( "Parent process waiting for signal/n" );
pause( );
printf( "Parent process waiting for child exit/n" );
ret=wait( &status );
}
else if( ret==0 )
{
printf( "This is the child process ( pid %d )/n",getpid( ) );
role=1;
pause( );
}
else
{
printf( "Can't create the child process!/n" );
}
printf( "%s:Exiting.../n",( role==0 )?"Parent":"Child" );
return 0;
}
//使用execlp的简单shell解释实例
#include <sys/types.h>
#include <sys/wait.h>
#include <wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LENGTH 80
int main( )
{
int status;
pid_t childpid;
char cmd[ MAX_LENGTH+1 ];
char* sret;
funcloop:
while( 1 )
{
printf( "mysh>" );
sret=fgets( cmd,sizeof( cmd ),stdin);
printf( "your command is :%s/n",cmd );
if( sret==NULL )
{
printf( "You have input nothing! Please input command:/n" );
goto funcloop;
//exit( -1 );
}
if( !strncmp(cmd, "bye",3 ) ) exit( 0 );
cmd[ strlen( cmd )-1 ]=0;
childpid=fork( );
if( childpid==0 )
{
execlp( cmd,cmd,NULL);
}
else if( childpid>0 )
{
waitpid( childpid,&status,0 );
goto funcloop;
}
}
free( cmd );
return 0;
}
/*参数和进程环境方面的问题
int execve( const char* filrname,char* const argv[ ],char* const envp[ ] );
char* envp[ ]={"PATH=/bin","FOO=99",NULL};
...
ret=execve( command,args,envp );
变量envp提供了一系列变量,为新创建的进程设置了环境。
*/
/*unsigned int alarm( unsigned int secs )
alarm在预先设定的时间长度达到时会发出一个SIGALRM信号,
在其他函数超时的情况下非常有用。
*/
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#define MAX_BUFFER 80
void wakeup( int sig_num )
{
raise( SIGKILL );
}
int main( )
{
char buffer[ MAX_BUFFER+1 ];
int ret;
signal( SIGALRM,wakeup );
printf( "You have 3 seconds to enter your password/n" );
alarm( 3 );
ret=read( 0,buffer,MAX_BUFFER );
//取消SIGALRM消息,以0参调用alarm即可
alarm( 0 );
if( ret==-1 )
printf( "Password wrong/n" );
else
{
buffer[ strlen( buffer )-1 ]=0;
printf( "User entered: %s/n",buffer );
}
return 0;
}
/*exit函数
viod exit( int status );
传入exit的参数会返回给父进程,为wait或waitpid调用提供所需要的状态信息。
exit调用时还会向父进程发送SIGCHLD信号,释放当前进程所占用的资源。
如果进程注册了atexit或on_exit函数,这些函数也会在退出时执行,调用顺序与它们的注册顺序相反。
*/
/*
POSIX标准信号API函数:sigaction( )
int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);
sigaction()提供的机制比传统的信号句柄更先进,而且有更强的兼容性。因此,应当使用sigaction来取代signal。
*/
//演示使用sigaction注册信号句柄的简单应用
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
static int stopChild=0;
void sigHandler( int sig,siginfo_t* siginfo,void* ignore )
{
printf( "Got SIGUSR1 from %d/n",siginfo->si_pid );
stopChild=1;
}
int main( )
{
pid_t ret;
int status;
int role=-1;
ret=fork( );
if( ret>0 )
{
printf( "Parent:this is the parent process ( pid %d )/n",getpid( ) );
//let the child init
sleep( 1 );
kill( ret,SIGUSR1 );
ret=wait( &status );
role=0;
}
else if( ret==0 )
{
struct sigaction act;
printf( "This is the child process ( pid %d )/n",getpid( ) );
act.sa_flags=SA_SIGINFO; //使用sa_sigaction指向的方法作为消息函数
act.sa_sigaction=sigHandler; //指向特定方法
sigaction( SIGUSR1,&act,0 );
printf( "Child waiting.../n" );
while( !stopChild );
role=1;
}
else
{
printf( "Parent: Error trying to fork( )( %d )/n",errno );
}
printf( "%s:Exiting.../n",( ( role==0 )?"Parent":"Child" ) );
return 0;
}