Linux进程编程实例

本文转自:http://blog.csdn.net/pcliuguangtao/article/details/6455118

  1. /*GUN/Linux进程有两种基本类型:内核线程和用户进程。 
  2.   用户进程由fork()和clone()创建。内核线程是由内核中的kernel_thread()创建。 
  3.   使用fork()创建子进程的时候,系统为它复制了父进程使用的内存部分映像,但是开始时他们都指向同一块内存, 
  4.   但是把内存页面标记为copy-on-write。当任何一个进程试图向这些内存中写入数据时,就会产生一组新的内存页面由这个进程私有。 
  5.   这提高了创建新进程的效率,因为内存空间的复制推迟到发生写操作的时候。默认情况下,子进程继承文件描述符、内容映像以及CPU状态(如PC和寄存器分配)。 
  6.   在调用fork的时候,父进程当时所有的变量对子进程都是可见的。但在fork执行完之后,父进程变量的任何改动对子进程来说都是不可见的。 
  7.  */  
  8. /*传统的进程API 
  9.   fork 创建一个新的子进程 
  10.   wait 将进程挂起直到任意一个子进程退出 
  11.   waitpid 将进程挂起直到指定的子进程退出 
  12.   signal 注册一个新的信号句柄 
  13.   pause 将进程挂起直到捕获到信号 
  14.   kill 向某个指定进程发送信号 
  15.   raise 向当前进程发送信号 
  16.   exec 将当前进程映像用一个新的进程映像替换 
  17.   exit 正常终止当前进程(退出) 
  18.  */  
  19.   
  20. //第一个进程实例  
  21. #include <stdio.h>  
  22. #include <unistd.h>  
  23. #include <sys/types.h>  
  24. int main(  )  
  25.     {  
  26.         pid_t myPid;  
  27.         pid_t myParentPid;  
  28.         gid_t myGid;  
  29.         uid_t myUid;  
  30.         myPid=getpid(  );  
  31.         myParentPid=getppid(  );  
  32.         myGid=getgid(  );  
  33.         myUid=getuid(  );  
  34.         printf( "my process id is %d/n",myPid );  
  35.         printf( "my parent's process id is %d/n",myParentPid );  
  36.         printf( "my user id is %d/n",myUid );  
  37.         printf( "my group id is %d/n",myGid );  
  38.         return 0;  
  39.           
  40.     }  
  41. //调用fork的应用实例  
  42. /* 
  43.   注意fork首先把CPU的控制权交给子进程。 
  44.   fork的返回值: 
  45.   On success, the PID of the child process is returned in the parent, 
  46.   and 0 is returned in the child.   On  failure,  -1 is returned in the parent, 
  47.   no child process is created, and errno is set appropriately. 
  48. */  
  49. #include <stdio.h>  
  50. #include <unistd.h>  
  51. #include <sys/types.h>  
  52. #include <errno.h>  
  53. #include <string.h>  
  54. #include <sys/wait.h>  
  55. int main(  )  
  56.     {  
  57.         pid_t ret;  
  58.         int status,i;  
  59.         int role=-1;  
  60.         ret=fork(  );  
  61.         if( ret==0 )  //child process  
  62.             {  
  63.                 printf( "Child:this is the child process ( pid %d )/n",getpid(  ) );  
  64.                 for( i=0;i<6;++i )  
  65.                     {  
  66.                         printf( "Child: at count %d /n ",i );  
  67.                         sleep( 1 );  
  68.                           
  69.                     }  
  70.                 role=1;  
  71.                   
  72.             }  
  73.         else if( ret>0 ) //parent process ,ret is the child process's pid  
  74.             {  
  75.                 printf( "Parent:this is the parent process ( pid %d )/n",getpid(  ) );  
  76.                 for( i=0;i<6;++i )  
  77.                     {  
  78.                         printf( "Parent: at count %d /n ",i );  
  79.                         sleep( 1 );  
  80.                     }  
  81.                 wait( &status );  
  82.                 role=0;  
  83.                   
  84.             }  
  85.         else  
  86.             {  
  87.                 printf( "Parent:Error trying to fork(  )( %s )/n",strerror(errno));  
  88.                   
  89.             }  
  90.         printf ( "%s:Exiting.../n",( (role==0)?"Parent":"Child" ) );  //both parent and child process execute  
  91.         return 0;  
  92.     }  
  93. /*信号,即GUN/Linux中进程的回调符号。可以为某个进程注册为在某事件发生时接受信号或 
  94.   是在某个默认操作退出时忽略信号。 
  95.  */  
  96. //为捕获信号注册句柄实例  
  97. #include <stdio.h>  
  98. #include <sys/types.h>  
  99. #include <signal.h>  
  100. #include <unistd.h>  
  101. void catch_ctlc( int sig_num )  
  102.     {  
  103.         printf( "/nCaught Ctrl+C/n" );  
  104.         fflush( stdout );  
  105.         return//可有可无  
  106.     }  
  107. int main(  )  
  108.     {  
  109.         //查看系统信号列表:man 7 signal  
  110.         signal( SIGINT,catch_ctlc );  
  111.         printf( "Go ahead,make my day/n" );  
  112.         //pause()causes the calling process (or thread) to sleep until a signal is delivered  
  113.         pause(  );  
  114.         return 0;  
  115.           
  116.     }  
  117. /************发出信号****************/  
  118. /* 
  119.   kill()可以向任意一个具有相应权限的进程发送信号并发挥作用; 
  120.   raise( sig )可以向自身进程发送信号 
  121.  */  
  122. //从子进程向父进程发出一个信号  
  123. #include <stdio.h>  
  124. #include <sys/types.h>  
  125. #include <sys/wait.h>  
  126. #include <unistd.h>  
  127. #include <signal.h>  
  128. #include <errno.h>  
  129. void usr1_handler( int sig_num )  
  130.     {  
  131.         printf( "Parent ( %d ) got the SIGUSR1/n",getpid(  ) );  
  132.     }  
  133. int main(  )  
  134.     {  
  135.         pid_t ret;  
  136.         int status;  
  137.         int role=-1;  
  138.         ret=fork(  );  
  139.         if( ret>0 )  
  140.             {  
  141.                 printf( "Parent:this is the parent process ( pid %d )/n",getpid(  ) );  
  142.                 signal( SIGUSR1,usr1_handler );  
  143.                 role=0;  
  144.                 pause(  );  
  145.                 printf( "Parent:waiting for child exit/n" );  
  146.                 ret=wait( &status );  
  147.                   
  148.             }  
  149.         else if( ret==0 )  
  150.             {  
  151.                 printf( "Child:this is the child process ( pid %d )/n",getpid(  ) );  
  152.                 role=1;  
  153.                 sleep( 1 ); //注意,当程序中出现sleep()的时候,就要注意对输出产生的滞后影响  
  154.                 printf( "Child:Sending SIGUSR1 to pid %d/n",getppid(  ) ); //此处的‘/n’不仅有换行的作用,还有刷新stdout的作用  
  155.                 //kill(pid,signal)可用于向某个进程发送信号  
  156.                 kill( getppid(  ),SIGUSR1 );  
  157.                 sleep( 2 );  
  158.                   
  159.             }  
  160.         else  
  161.             {  
  162.                 printf( "Parent:Error trying to fork(  )( %s )/n",strerror(errno));  
  163.             }  
  164.         printf("/n%s:Exiting.../n",( (role==0)?"Parent":"Child" ));  
  165.         return 0;  
  166.     }  
  167. /*这个例子中父子进程都没有发送SIGUSR1信号 
  168.   这个例子可用于展示进程间进行异步通讯的有力方法 
  169.   ./test & 
  170.   kill -s 10 -p parent'pid   // 10 represent SIGUSR1 
  171.   kill -s SIGUSR1 -p child'pid 
  172.  */  
  173. #include <stdio.h>  
  174. #include <sys/types.h>  
  175. #include <sys/wait.h>  
  176. #include <unistd.h>  
  177. #include <signal.h>  
  178. #include <error.h>  
  179. void usr1_handler( int sig_num )  
  180.     {  
  181.         printf( "Process ( %d ) got the SIGUSR1/n",getpid(  ) );  
  182.     }  
  183. int main(  )  
  184.     {  
  185.         pid_t ret;  
  186.         int status;  
  187.         int role=-1;  
  188.         signal( SIGUSR1,usr1_handler );  
  189.         ret=fork(  );  
  190.         if( ret>0 )  
  191.             {  
  192.                 printf("This is parent process ( pid %d )/n",getpid(  ));  
  193.                 role=0;  
  194.                 printf( "Parent process waiting for signal/n" );  
  195.                 pause(  );  
  196.                 printf( "Parent process waiting for child exit/n" );  
  197.                 ret=wait( &status );  
  198.             }  
  199.         else if( ret==0 )  
  200.             {  
  201.                 printf( "This is the child process ( pid %d )/n",getpid(  ) );  
  202.                 role=1;  
  203.                 pause(  );  
  204.                   
  205.             }  
  206.         else  
  207.             {  
  208.                 printf( "Can't create the child process!/n" );  
  209.             }  
  210.         printf( "%s:Exiting.../n",( role==0 )?"Parent":"Child" );  
  211.         return 0;  
  212.     }  
  213. //使用execlp的简单shell解释实例  
  214. #include <sys/types.h>  
  215. #include <sys/wait.h>  
  216. #include <wait.h>  
  217. #include <stdio.h>  
  218. #include <stdlib.h>  
  219. #include <string.h>  
  220. #define MAX_LENGTH 80  
  221. int main(  )  
  222.     {  
  223.         int status;  
  224.         pid_t childpid;  
  225.         char cmd[ MAX_LENGTH+1 ];  
  226.         char* sret;  
  227.     funcloop:  
  228.         while( 1 )  
  229.             {     
  230.                 printf( "mysh>" );  
  231.                 sret=fgets( cmd,sizeof( cmd ),stdin);  
  232.                 printf( "your command is :%s/n",cmd );  
  233.                   
  234.                 if( sret==NULL )  
  235.                 {  
  236.                     printf( "You have input nothing! Please input command:/n" );  
  237.                     goto funcloop;  
  238.                     //exit( -1 );  
  239.                 }  
  240.                 if( !strncmp(cmd, "bye",3 ) ) exit( 0 );  
  241.                 cmd[ strlen( cmd )-1 ]=0;  
  242.                 childpid=fork(  );  
  243.                 if( childpid==0 )  
  244.                     {  
  245.                         execlp( cmd,cmd,NULL);  
  246.                     }  
  247.                 else if( childpid>0 )  
  248.                     {  
  249.                         waitpid( childpid,&status,0 );  
  250.                         goto funcloop;                          
  251.                     }  
  252.             }  
  253.           
  254.         free( cmd );  
  255.         return 0;  
  256.           
  257.           
  258.     }  
  259. /*参数和进程环境方面的问题 
  260.   int execve( const char* filrname,char* const argv[  ],char* const envp[  ] ); 
  261.   char* envp[  ]={"PATH=/bin","FOO=99",NULL}; 
  262.   ... 
  263.   ret=execve( command,args,envp ); 
  264.   变量envp提供了一系列变量,为新创建的进程设置了环境。 
  265.  */  
  266. /*unsigned int alarm( unsigned int secs ) 
  267.   alarm在预先设定的时间长度达到时会发出一个SIGALRM信号, 
  268.   在其他函数超时的情况下非常有用。 
  269.  */  
  270. #include <stdio.h>  
  271. #include <unistd.h>  
  272. #include <signal.h>  
  273. #include <string.h>  
  274. #define MAX_BUFFER 80  
  275. void wakeup( int sig_num )  
  276.     {  
  277.         raise( SIGKILL );  
  278.     }  
  279. int main(  )  
  280.     {  
  281.         char buffer[ MAX_BUFFER+1 ];  
  282.         int ret;  
  283.         signal( SIGALRM,wakeup );  
  284.         printf( "You have 3 seconds to enter your password/n" );  
  285.         alarm( 3 );  
  286.         ret=read( 0,buffer,MAX_BUFFER );  
  287.         //取消SIGALRM消息,以0参调用alarm即可  
  288.         alarm( 0 );  
  289.         if( ret==-1 )  
  290.             printf( "Password wrong/n" );  
  291.         else  
  292.             {  
  293.                 buffer[ strlen( buffer )-1 ]=0;  
  294.                 printf( "User entered: %s/n",buffer );  
  295.                   
  296.             }  
  297.         return 0;  
  298.           
  299.     }  
  300. /*exit函数 
  301.   viod exit( int status ); 
  302.   传入exit的参数会返回给父进程,为wait或waitpid调用提供所需要的状态信息。 
  303.   exit调用时还会向父进程发送SIGCHLD信号,释放当前进程所占用的资源。 
  304.   如果进程注册了atexit或on_exit函数,这些函数也会在退出时执行,调用顺序与它们的注册顺序相反。 
  305.  */  
  306. /* 
  307.   POSIX标准信号API函数:sigaction( ) 
  308.   int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact); 
  309.   sigaction()提供的机制比传统的信号句柄更先进,而且有更强的兼容性。因此,应当使用sigaction来取代signal。 
  310.  */  
  311. //演示使用sigaction注册信号句柄的简单应用  
  312. #include <stdio.h>  
  313. #include <sys/types.h>  
  314. #include <sys/wait.h>  
  315. #include <signal.h>  
  316. #include <unistd.h>  
  317. #include <errno.h>  
  318. static int stopChild=0;  
  319. void sigHandler( int sig,siginfo_t* siginfo,void* ignore )  
  320.     {  
  321.         printf( "Got SIGUSR1 from %d/n",siginfo->si_pid );  
  322.         stopChild=1;  
  323.     }  
  324. int main(  )  
  325.     {  
  326.         pid_t ret;  
  327.         int status;  
  328.         int role=-1;  
  329.         ret=fork(  );  
  330.         if( ret>0 )  
  331.             {  
  332.                 printf( "Parent:this is the parent process ( pid %d )/n",getpid(  ) );  
  333.                 //let the child init  
  334.                 sleep( 1 );  
  335.                 kill( ret,SIGUSR1 );  
  336.                 ret=wait( &status );  
  337.                 role=0;  
  338.                   
  339.             }  
  340.         else if( ret==0 )  
  341.             {  
  342.                 struct sigaction act;  
  343.                 printf( "This is the child process ( pid %d )/n",getpid(  ) );  
  344.                 act.sa_flags=SA_SIGINFO;   //使用sa_sigaction指向的方法作为消息函数  
  345.                 act.sa_sigaction=sigHandler;   //指向特定方法  
  346.                 sigaction( SIGUSR1,&act,0 );  
  347.                 printf( "Child waiting.../n" );  
  348.                 while( !stopChild );  
  349.                 role=1;  
  350.                   
  351.             }  
  352.         else  
  353.             {  
  354.                 printf( "Parent: Error trying to fork(  )( %d )/n",errno );  
  355.             }  
  356.         printf( "%s:Exiting.../n",( ( role==0 )?"Parent":"Child" ) );  
  357.         return 0;  
  358.           
  359.     }  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值