Linux下进程编程

来源:互联网 发布:闲鱼淘宝介入后谁会赢 编辑:程序博客网 时间:2024/05/18 02:26

Linux下进程编程

写给linux编程的初学者,进程编程是linux编程首先要学习的东西,往后要学习进程之间通讯的一些编程。下面的是进程编程的一些基本函数。

1.    用户标识(UID)和有效用户标识(EUID)

使用getuid函数和geteuid函数来获取当前进程的用户标识和有效用户标识

#include <stdio.h>

#include <sys/types.h>

#include <unistd.h>

int main(void){

       printf("Current process UID : %ld\n",(long)getuid());

       printf("Current porcess EUID : %ld\n",(long)geteuid());

       return 0;

}

 

运行结果:

Current process UID:500

Current process EUID:500

 

2. fork函数

通过fork函数并判断函数返回值,根据返回值来判断是在父进程还是子进程。

#include <stdio.h>

#include <unistd.h>

#include <sys/types.h>

int main(void){

       pid_t pid;

//fork函数如果返回值小于0,表示调用失败

//如果返回值为0,表示处于进程中,如果大于0,表示在父进程中

       if((pid=fork())<0){

              perror("Cannot create the new process");

              return 1;

       }else if(pid==0){

              printf("In the child process!\n");

              return 0;

       }else {

              printf("In the parent process!\n");

              return 0;

       }

}

运行结果:

In the child processs!!

In the parent process!!

调用fork函数后,其后代码会被父子进程分别执行。

#include <stdio.h>

#include <unistd.h>

#include <sys/types.h>

int main(void){

       fork();

       printf("Will be executed twice\n");

       return 0;

}

 

运行结果:

Will be excuted twice

Will be excuted twice

 

3. vfork函数

首先定义g_var为全局变量, var为局部变量,然后调用fork函数创建子进程,并在子进程对g_var变量和var变量进行修改。子进程在输出这两个变脸值后退出,输出父进程中的这两个变量的取值情况。

#include <stdio.h>

#include <unistd.h>

#include <sys/types.h>

int g_var=0;

int main(void){

       pid_t pid;

       int var=1;

       printf("process id:%ld\n",(long)getpid());

       printf("before execute the fork system call, g_var=%d var=%d\n",g_var,var);

       if((pid=fork())<0){

              perror("Cannot create a new process");

              return 1;

       }else if(pid==0){

              g_var++;

              var++;

              printf("process id : %ld, g_var=%d var=%d\n",(long)getpid(),g_var,var);

              _exit(0);

       }

       printf("process id : %ld, g_var=%d var=%d\n",(long)getpid(),g_var,var);

       return 0;

}

 

运行结果:

Process id :24437

Before excute the fork system call,g_var=0 var=1

Process id :24438, g_var=1 var=2

Process id :24437, g_var=0 var=1

修改上面的程序,将fork函数的语句进行替换,使用vfork函数,将代码保存并运行

#include <stdio.h>

#include <unistd.h>

#include <sys/types.h>

int g_var=0;

int main(void){

       pid_t pid;

       int var=1;

         printf("process id:%ld\n",(long)getpid());

         printf("before execute the fork system call, g_var=%d var=%d\n",g_var,var);

       if((pid=vfork())<0){

              perror("Cannot create a new process");

              return 1;

       }else if(pid==0){

              g_var++;

              var++;

              printf("process id : %ld, g_var=%d var=%d\n",(long)getpid(),g_var,var);

              _exit(0);

       }

       printf("process id : %ld, g_var=%d var=%d\n",(long)getpid(),g_var,var);

       return 0;

}

 

运行结果:

Process id :24574

Before excute the fork system call,g_var=0 var=1

Process id :24575, g_var=1 var=2

Process id :24574, g_var=1 var=2

 

4         exec 函数族

execvp函数支持参数列表,使用参数列表将使程序获得更大的灵活性,程序通过读取agrv中的参数,实现对输入的shell命令的执行。

#include <stdio.h>

#include <unistd.h>

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;

}

 

5  exit函数

使用atexit注册了一个在进程退出时的处理函数,该处理函数只是显示一段文字信息。Main函数退出时将调用exit函数,这样进程就会在退出时自动调用atexit注册的处理函数。

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

void do_at_exit(void)

{

       printf("You can see the output when the program terminates\n");

}

int main(){

       int flag;

       flag=atexit(do_at_exit);

       if (flag != 0) {

              printf("Cannot set exit function\n");

             return EXIT_FAILURE;

       }

              exit(EXIT_SUCCESS);

}

 

6  _exit函数

下面的程序和上面的除了退出函数不同,其他都一样。不同的是使用_exit函数退出时,不会执行atexit中注册的处理函数

 

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

void do_at_exit(void)

{

       printf("You can see the output when the program terminates\n");

}

int main(){

       int flag;

       flag=atexit(do_at_exit);

       if (flag != 0) {

              printf("Cannot set exit function\n");

             return EXIT_FAILURE;

       }

     _exit(EXIT_SUCCESS);

}

 

7  kill 函数发送信号

直接用kill函数给进程发送结束信号或是让程序自动退出。

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <sys/types.h>

int main(int argc,char* argv[]){

       pid_t pid;

       int exit_code;

       pid=getpid();

       srand((unsigned)pid);

       exit_code=(int)(rand() % 256);

       sleep(10);

       if(atoi(*(argv+1)) % 2){

              printf("the child process id:%d receive signal SIGKILL\n",pid);

              kill(pid,9);

       }else{

              printf("the child process id:%d normally exit,exit_code is %0x\n",pid,exit_code);

              exit(exit_code);

       }

}

下面程序通过fork函数创建子进程,并调用execl函数执行上面的程序。为了方便了解程序运行情况,在父进程中显示了创建的子进程的进程号。在while循环中调用wait函数,跳出条件是wait函数放回值小于0,或wait_pid为-1。这种情况下,所有的子进程都已经完全退出。

#include <stdio.h>

#include <unistd.h>

#include <sys/types.h>

#include <sys/wait.h>

int main(int argc,char* argv[]){

       pid_t pid,wait_pid;

       int status;

       int i;

       if(argc<4){

              printf("Usage: %s para1 para2 para3\n",argv[0]);

              return 1;

       }

       for(i=1;i<4;i++)

              if((pid=fork())==0)

                     execl("./p7.14","p7.14",argv[i],NULL);

              else

              printf("create the child process id: %d\n",pid);

       while((wait_pid=wait(&status)) && wait_pid!=-1)

              printf("process id:%d exit,exit_code is %0x\n",wait_pid,status);

              return 0;

}

 

8  waitpid函数

使用waitpid等待SIGSTOP,SIGCONT和SIGKILL这3种信号.

#include <stdio.h>

#include <sys/wait.h>

#include <stdlib.h>

#include <unistd.h>

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);

          }

}

 

9. 僵尸进程

#include <stdlib.h>

#include <sys/types.h>

#include <unistd.h>

 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;

原创粉丝点击