1、获取ID
//包含两个头文件
#include <sys/types.h>
#include <unistd.h>
vpid_t getpid(void) //获取本进程ID。
//vpid_t是Linux下的进程号类型,其实是宏定义的unsigned int类型
pid_t getppid(void) //获取父进程ID。
//pid_t是Linux下的进程号类型,也就是Process ID _ Type 的缩写。 其实是宏定义的unsigned int类型
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(void)
{
printf( "PID = %d\n", getpid() );
printf( "PPID = %d\n", getppid() );
return 0;
}
#include <unistd.h>
#include <sys/types.h>
pid_t fork(void)
功能:创建子进程
fork的奇妙之处在于它被调用一次,却返回两次,它可能有三种不
同的返回值:
1). 在父进程中,fork返回新创建的子进程的PID;
2). 在子进程中,fork返回0;
3). 如果出现错误,fork返回一个负值
#include<unistd.h>
#include<sys/types.h>
函数原型:pid_t fork( void);(pid_t 是一个宏定义,其实质是int 被定义在#include<sys/types.h>中)
返回值: 若成功调用一次则返回两个值,子进程返回0,返回子进程ID;否则,出错返回-1
fork.c
#include <sys/types.h>
#include <unistd.h>
main()
{
pid_t pid;
/*此时仅有一个进程*/
pid=fork();
/*此时已经有两个进程在同时运行*/
if(pid<0)
printf("error in fork!");
else if(pid==0)
printf("I am the child process, ID is %d\n",getpid());
else
printf("I am the parent process,ID is %d\n",getpid());
}
代码解读:在pid=fork()之前,只有一个进程在执行,但在这条语句执行之后,就变成两个进程在执行了,这两个进程的共享代码段,将要执行的下一条语句都是if(pid==0)。 两个进程中,原来就存在的那个进程被称作“父进程”,新出现的那个进程被称作“子进程”,父子进程的区别在于进程标识符(PID)不同。
3、进程创建-vfork
#include <sys/types.h>#include <unistd.h>
pid_t vfork(void)
功能:创建子进程。
fork PK vfork
区别:
1. fork:子进程拷贝父进程的数据段
vfork:子进程与父进程共享数据段
2. fork:父、子进程的执行次序不确定
vfork:保证子进程先运行,在调用exec或_exit之前与 父进程数据是共享的,在它调用exec或_exit之后 父进程才可能被调度运行。
3、当需要改变共享数据段中变量的值,则拷贝父进程。
#include <unistd.h>
#include <stdio.h>
int main(void)
{
pid_t pid;
int count=0;
pid = vfork();
count++;
printf( “count = %d\n", count );
return 0;
}
exec用被执行的程序替换调用它的程序。
区别:
fork创建一个新的进程,产生一个新的PID。exec启动一个新程序,替换原有的进程,因此进程的PID不会改变。
说是exec系统调用,实际上在Linux中,并不存在一个exec()的函数形式,exec指的是一组函数,一共有6个,分别是:
#include <unistd.h>
extern char **environ;
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg, ..., char * const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execve(const char *path, char *const argv[], char *const envp[]);
其中只有execve是真正意义上的系统调用,其它都是在此基础上经过包装的库函数。
1)
#include<unistd.h>
int execl(const char * path,const char * arg1, ....)
参数:
path:被执行程序名(含完整路径)。
arg1 – argn: 被执行程序所需的命令行参数,含程序名。以空指针(NULL)结束。
函数说明:execl()其中后缀"l"代表list也就是参数列表的意思,第一参数path字符指针所指向要执行的文件路径, 接下来的参数代表执行该文件时传递的参数列表:argv[0],argv[1]... 最后一个参数须用空指针NULL作结束。
execl.c
#include <unistd.h>
main()
{
execl(“/bin/ls”,”ls”,”-al”,”/etc/passwd”,(char * )0);
}
2)
#include<unistd.h>
int execlp(const char * path,const char * arg1, ...)
函数说明:execlp()会从PATH 环境变量所指的目录中查找符合参数file的文件名,找到后便执行该文件,然后将第二个以后的参数当做该文件的argv[0]、argv[1]……,最后一个参数必须用空指针(NULL)作结束。如果用常数0来表示一个空指针,则必须将它强制转换为一个字符指针,否则将它解释为整形参数,如果一个整形数的长度与char * 的长度不同,那么exec函数的实际参数就将出错。如果函数调用成功,进程自己的执行代码就会变成加载程序的代码,execlp()后边的代码也就不会执行了.
参数:
path:被执行程序名(不含路径,将从path环境变量中查找该程序)。
arg1 – argn: 被执行程序所需的命令行参数,含程序名。以空指针(NULL)结束。
返回值:如果执行成功则函数不会返回,执行失败则直接返回-1,失败原因存于errno 中。
execlp.c
#include<unistd.h>
main()
{
execlp(”ls”,”ls”,”-al”,”/etc/passwd”,(char *)0);
}
3)
#include<unistd.h>
int execv (const char * path, char * const argv[ ])
功 能: 装入并运行其它程序的函数
参数:
path:被执行程序名(含完整路径)。
argv[]: 被执行程序所需的命令行参数数组。
#include <unistd.h>
main()
{
char * argv[ ]={“ls”,”-al”,”/etc/passwd”,(char*)0};
execv(“/bin/ls”,argv);
}
4)
execvp.c
#include<unistd.h>
main()
{
char * argv[ ] ={ “ls”,”-al”,”/etc/passwd”,0};
execvp(“ls”,argv);
}
5)
#include<unistd.h>
int execve(const char * filename,char * const argv[ ],char * const envp[ ]);
函数说明:execve()用来执行参数filename字符串所代表的文件路径,第二个参数是利用数组指针来传递给执行文件,并且需要以空指针(NULL)结束,最后一个参数则为传递给执行文件的新环境变量数组。
返回值:
#include<unistd.h>
main()
{
char * argv[ ]={"ls","-al","/etc/passwd",(char *)0};
char * envp[ ]={"PATH=/bin",0};
execve("/bin/ls",argv,envp);
}
6)
#include<unistd.h>
int execle(const char * path,const char * arg,....,char *const envp[]);
5、
#include <stdlib.h>
int system( const char* string )
功能:
调用fork产生子进程,由子进程来调用
/bin/sh -c string来执行参数string所代表
的命令。
system.c
#include <stdlib.h>
void main()
{
system(“ls -al /etc/passwd”);
}
6、进程等待
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait (int * status)
功能:
阻塞该进程,直到其某个子进程退出。
wait.c
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
void main()
{
pid_t pc,pr;
pc=fork();
if (pc==0){ /* 如果是子进程 */
printf(“This is child process with pid of %d\n”,getpid());
sleep(10); /* 睡眠10秒钟 */
}
else if (pc>0){ /* 如果是父进程 */
pr=wait(NULL); /* 等待 */
printf("I catched a child process with pid of %d\n"),pr);
}
exit(0);
}