fork and signal

来源:互联网 发布:淘宝客手机网站搭建 编辑:程序博客网 时间:2024/05/18 14:25

int main(void){

printf("Will be executed one \n"); 仅执行一次
 fork();
 printf("Will be executed twice\n");  将被执行两次。
 return 0;
}

fork:

#include <stdio.h>
#include <sched.h>

int data = 10;

int child_process()
{
 printf("Child process %d, data %d\n",getpid(),data);
 data = 20;
 printf("Child process %d, data %d\n",getpid(),data);
 while(1);
}

int main(int argc, char* argv[])
{
 int pid;
 pid = fork();
 
 if(pid==0) {
  child_process(); 
 }
 else{
  sleep(1);
  printf("Parent process %d, data %d\n",getpid(), data);
  while(1);
 }
}

运行结果:

lihacker@lihacker-laptop:~$ ./fork
Child process 18604, data 10
Child process 18604, data 20
Parent process 18603, data 10

 父子进程运行 改变变量互不影响。

vfork :

int data = 10;

int child_process()
{
 printf("Child process %d, data %d\n",getpid(),data);
 data = 20;
 printf("Child process %d, data %d\n",getpid(),data);
 //while(1);
}

int main(int argc, char* argv[])
{
 if(vfork()==0) {
  child_process(); 
 }
 else{
  sleep(1);
  //这里data 将会和子进程中被改变的一样,变量值将会相互影响。
  printf("Parent process %d, data %d\n",getpid(), data);
  while(1);      ////发信号kill子进程
                      //kill(pid,SIGKILL);
 }
}

lihacker@lihacker-laptop:~$ ./vfork
Child process 18843, data 10
Child process 18843, data 20
Parent process 18842, data 20

execlp :

int main(int argc,char* argv[]){
 if(argc<2){
  printf("Usage:  %s path\n",argv[0]);
  return 1; 
 }

 execlp("/bin/ls","ls",argv[1],(char*)NULL);//调用之后即不返回
 return 0;
}

 char * argv[ ] ={ “ls”,”-al”,”/etc/passwd”,0};

  execvp(“ls”,argv);

signal :

void handle(int sig)
{
    pid_t pid;
 while((pid=waitpid(-1,NULL,0))>0)
  {
  printf("handle signal");
  }
 sleep(1);
 return ;
}
int main()
{
pid_t pid;
    if(signal(SIGCHLD,handle)==SIG_ERR)
  perror("cannot reset the SIGCHLOD signal handler");
  return 1;
  for(int i=0;i<3;i++)
   {
   pid=fork();
             if(pid==0)
              {
              printf("child %d"\n,(int)getpid());
    sleep(1);
              }
  }
  pause();
}

kill(pid,9);  、、也用于结束进程
sigaction:

定义函数 int sigaction(int signum,const struct sigaction *act ,struct sigaction *oldact);

  函数说明 sigaction()会依参数signum指定的信号编号来设置该信号的处理函数。参数signum可以指定SIGKILL和SIGSTOP以外的所有信号。

参数结构sigaction定义如下
struct sigaction
{
void (*sa_handler) (int);
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer) (void);
}

#include <stdio.h>
#include <signal.h>

void signal_set(struct sigaction *act)
{
        switch(act->sa_flags){
  case (int)SIG_DFL:
   printf("using default hander\n");
   break;
  case (int)SIG_IGN:
   printf("ignore the signal\n");
   break;
  default:
   printf("%0x\n",act->sa_handler);
      }
}

int main(int argc,char** argv)
{
        int i;
        struct sigaction act,oldact;
       
 act.sa_handler = signal_set;
        act.sa_flags = SA_NODEFER| SA_RESETHAND;
       
 sigaction (SIGUSR1,&act,&oldact) ;

 for (i=1; i<12; i++){
                printf("signal %d handler is : ",i);
                sigaction (i,NULL,&oldact) ;
                signal_set (&oldact);
        }

        return 0;
}

 int status;

while((wait_pid=wait(&status)) && wait_pid!=-1)
  printf("process id:%d exit,exit_code is %0x\n",wait_pid,status);
 

while((wait_pid=wait(&status)) && wait_pid!=-1){
                if(WIFSIGNALED(status))
       printf("process id:%d Receive SIG :%d exit\n",pid,WTERMSIG(status));
  
  if(WIFEXITED (status))
   printf("process id:%d exit code %d\n",pid,WEXITSTATUS(status));
 }

   wait :

int main(void)
{
 pid_t pid,wait_pid;
 int status;
       
      pid = fork();
    
   if (pid==-1) {
         perror("Cannot create new process");
  exit(1);
 } else  if (pid==0) {     
               printf("child process id: %ld\n", (long) getpid());
                  
        pause();
               _exit(0);
           } else {                   
     do {
      wait_pid=waitpid(pid, &status, WUNTRACED | WCONTINUED);
   
      if (wait_pid == -1) {
       perror("cannot using waitpid function");
       exit(1);
      }
     ///    调用定义的宏来判断进程是何种退出方式示例          
      if (WIFEXITED(status))
       printf("child process exites, status=%d\n", WEXITSTATUS(status));
     
      if(WIFSIGNALED(status))
       printf("child process is killed by signal %d\n", WTERMSIG(status));
     
      if (WIFSTOPPED(status))
       printf("child process is stopped by signal %d\n", WSTOPSIG(status));
     
      if (WIFCONTINUED(status))
       printf("child process resume running....\n");
              
     } while (!WIFEXITED(status) && !WIFSIGNALED(status));
              
     exit(0);
    }
}

产生僵尸进程:一个进程结束了,但是他的父进程没有等待(调用wait / waitpid)他, 那么他将变成一个僵尸进程. 但是如果该进程的父进程已经先结束了,那么该进程就不会变成僵尸进程, 因为每个进程结束的时候,系统都会扫描当前系统中所运行的所有进程, 看有没有哪个进程是刚刚结束的这个进程的子进程,如果是的话,就由Init 来接管他,成为他的父进程……

int main (void)
{
  pid_t pid;
 
  pid = fork();

  if(pid<0){
   perror("cannot create new process");
 exit(1);
  }

  if (pid>0)
    sleep (60);
  else
    exit (0);
  return 0;
}

 

void  main()
{

  pid_t pid;
 /* char buf[128];
 
  if(write(stout,buf,sizeof(buf))!=sizeof(buf)-1)
   printf("write_error");*/
  if((pid=fork())<0)// fork +exec :--->swap 运行新的进程
   {
   printf("fork error");
   }
  else if(pid==0)
   {
//子进程,进程的运行有两种方式,即 独立运行和使用父进程运行
//父进程已经终止的进程(孤儿进程)由init (ID=1)领养
//ID==0 调度进程-- 交换进程(swapper) : 系统进程
//ID==2 :页守护进程:支持虚拟存储系统的分页操作
        printf("set up signal handle");
   signal(SIGUSR1,sig_usr); //建立signal handle
        printf("kill self");
   kill(getpid(),SIGTSTP); //STOP itself
   }
  else
   {
   sleep(5);//父进程休息,先运行子进程,没有这个,父子进程先后执行顺序不确定
             //子进程在父地址空间中运行
        printf("father running");
   }       
   exit(0);
}
 

原创粉丝点击