进程指的是正在运行的程序。
下图是进程的三种状态:
后台进程又叫守护进程。
每个进程都有一个唯一的标识符,即进程ID,简称pid。
include
pid_t fork(void)
getpid()
getppid()
#include
#include
int main(int argc, char** argv)
{
pid_t pid;
pid = fork();
if(pid < 0)
{
printf("fork is error\n");
return -1;
}
// parent process
if(pid > 0)
{
printf("This is parent, parent pid is %d\n", getpid());
}
// child process
if(pid == 0)
{
printf("This is child, child pid is %d, parent pid is %d\n", getpid(), getppid());
}
return 0;
}
$ gcc main.c -o main.out
$ ./main.out
This is parent, parent pid is 17937
This is child, child pid is 17938, parent pid is 17937
#include
#include
int main(int argc, char** argv)
{
pid_t pid;
pid = fork();
if(pid < 0)
{
printf("fork is error\n");
return -1;
}
// parent process
if(pid > 0)
{
printf("This is parent, parent pid is %d\n", getpid());
while(1)
{
printf("This is parent, parent pid is %d\n", getpid());
}
}
// child process
if(pid == 0)
{
printf("This is child, child pid is %d, parent pid is %d\n", getpid(), getppid());
while(1)
{
printf("This is child, child pid is %d\n", getpid());
}
}
return 0;
}
$ gcc main.c -o main.out
$ ./main.out
This is parent, parent pid is 18134
This is child, child pid is 18135, parent pid is 18134
This is parent, parent pid is 18134
This is child, child pid is 18135
This is parent, parent pid is 18134
This is child, child pid is 18135
This is parent, parent pid is 18134
This is child, child pid is 18135
This is parent, parent pid is 18134
This is child, child pid is 18135
This is parent, parent pid is 18134
This is child, child pid is 18135
This is parent, parent pid is 18134
This is child, child pid is 18135
This is parent, parent pid is 18134
This is child, child pid is 18135
This is parent, parent pid is 18134
This is child, child pid is 18135
This is parent, parent pid is 18134
This is child, child pid is 18135
This is parent, parent pid is 18134
This is child, child pid is 18135
This is parent, parent pid is 18134
This is child, child pid is 18135
This is parent, parent pid is 18134
This is child, child pid is 18135
This is parent, parent pid is 18134
This is child, child pid is 18135
This is parent, parent pid is 18134
...
#include
#include
int main(int argc, char** argv)
{
int cnt = 0;
pid_t pid;
pid = fork();
if(pid < 0)
{
printf("fork is error\n");
return -1;
}
// parent process
if(pid > 0)
{
printf("This is parent, parent pid is %d\n", getpid());
}
// child process
if(pid == 0)
{
printf("This is child, child pid is %d, parent pid is %d\n", getpid(), getppid());
}
cnt++;
printf("cnt: %d, pid: %d\n", cnt, getpid());
return 0;
}
测试运行:
$ gcc main.c -o main.out
$ ./main.out
This is parent, parent pid is 18180
cnt: 1, pid: 18180
This is child, child pid is 18181, parent pid is 18180
cnt: 1, pid: 18181
这里就是说cnt变量在父进程和子进程里面是独立的拷贝,所以结果不是2而是1.
在Linux中并没有exec函数,而是有6个以exec开头的函数族,下面列举了exec函数族的6个函数成员:
int execl(const char *path, const char *arg, ...)
int execv(const char *path, char *const arg[], ...)
int execle(const char *path, const char *arg, ..., char *const envp[])
int execve(const char *path,char *const arg[], ..., char *const envp[])
int execlp(const char *file, const char *arg, ...)
int execvp(const char *file, char *const arg[], ...)
头文件是:unistd.h
最常用的函数是execl函数
exec函数族可以让子进程执行不同的代码
在Linux中使用exec函数族主要有以下两种情况:
两个代码:
hello.c
#include
int main(int argc, char** argv)
{
printf("Hello World!\n");
return 0;
}
main.c
#include
#include
#include
int main(int argc, char** argv)
{
int cnt = 0;
pid_t pid;
pid = fork();
if(pid < 0)
{
printf("fork is error\n");
return -1;
}
// parent process
if(pid > 0)
{
printf("This is parent, parent pid is %d\n", getpid());
}
// child process
if(pid == 0)
{
printf("This is child, child pid is %d, parent pid is %d\n", getpid(), getppid());
// 启动另一个程序hello.out
execl("/home/liefyuan/Linux/app/08-fork/hello.out", "hello", NULL);
// execl("/bin/ls","ls", "-al", NULL);
exit(1);
}
cnt++;
printf("cnt: %d, pid: %d\n", cnt, getpid());
return 0;
}
测试运行:
liefyuan@ubuntu:~/Linux/app/08-fork$ ./main.out
This is parent, parent pid is 18467
cnt: 1, pid: 18467
This is child, child pid is 18468, parent pid is 18467
Hello World!
只有一次cnt的打印还是父进程打印的,子进程没有cnt打印。
execl函数是“换核不换壳”的,将子进程的内容直接替换成了hello.out程序,而原有的子进程的逻辑就不会再跑了。
ps命令:可以列出系统中当前运行的哪些进程。
举例:
ps aux
进程不关联终端ps a
和 ps u
都是进程关联终端的ps x
显示所有程序,不以终端来区分ps aux | grep xxx
中间竖线是管道的意思,相当是过滤,除了xxx的都不显示[root@RK356X:/]# ps a
PID TTY STAT TIME COMMAND
765 ttyFIQ0 Ss 0:00 -/bin/sh
3579 ttyFIQ0 R+ 0:00 ps a
[root@RK356X:/]# ps au
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 765 0.0 0.1 3168 2068 ttyFIQ0 Ss 11:40 0:00 -/bin/sh
root 3580 0.0 0.0 2992 844 ttyFIQ0 R+ 12:57 0:00 ps au
kill命令:用来杀死进程。
举例:kill -9(SIGKILL) PID
可以是使用kill -l
来查看所有的相关命令:
$ kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX