linux系统的进程控制

1.进程概念

进程是一个具有独立功能的程序的一次动态执行过程,简单的说,进程就是正在执行的程序。进程与程序不同,程序是永久的,静态的,而进程是暂时的,动态的。一个程序可以多次加载到内存中成为多个进程。

linux中的进程都由其它进程所创建(除了pid为0号的idle进程),创建新进程的进程叫父进程,新进程叫子进程。

2.进程的标识

在linux系统中,最重要的进程标识是进程号(Process Idenity Number,PID)。PID能唯一标识一个进程,PID是一个非零正整数。

获取当前进程PID的函数:pid_t  getpid(void);

获取当前进程的父进程PID的函数 pid_t  getppid(void);

测试代码:

#include<stdio.h>
#include<unistd.h>
int main(void)
{
   printf("PID = %d \n",getpid());//打印进程PID
   printf("PPID = %d\n",getppid());//打印父进程PID
   return 0;
}

测试结果:

可以看到,该进程ID为3741,其父进程ID为2818

3.创建进程

创建新进程的函数为fork(),其函数原型为:

pid_t fork(void);

fork函数调用进程失败会返回-1,调用成功会返回两次:在父进程中返回子进程的PID,在子进程中返回0。执行fork后,子进程和父进程将具有相同的程序和数据。

测试代码:

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>

int a=0;
int main(void)
{
	int b=0;
	int pid=0;

	a++;
	b++;

	printf("a=%d,b=%d\n",a,b);
	pid=fork();
	a++;
	b++;
	printf("a=%d,b=%d\n",a,b);
	printf("pid=%d\n",pid);

	return 0;

}

测试结果:

可以看到,在执行fork后,父子进程打印的a,b值相同,说明两个进程有各自的数据区和用户堆栈。

4.进程控制

调用fork函数,子进程与父进程执行的程序相同,为了使子进程执行不同的函数,需要调用exec函数,调用该函数后该进程的用户空间代码和数据完全被新程序替换掉,从而让子进程成为一个真正的新进程。exec函数包括6种以exec开头的函数:

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, const char* argv[]);
int execvp(const char* file, const char* argv[]);
int execve(const char* path, const char* argv[], char* const envp[]);

参数path为可执行文件路径,argv为命令行参数。参数列表的最后必须以NULL结束。

测试代码:

#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>

int main(void)
{
   int pid;
   pid=fork();
   if(pid==0)//子进程中执行hello
   {
     execv("./hello",NULL);
   }
   else//父进程中打印子进程PID
   {
     printf("PID of new process is :%d\n",pid);
   }
   return 0;
}

运行结果:

新建进程的PID为3949,在新进程中执行了hello程序,并打印出了“hello,world”字符串。

5.system函数

system函数可以在一个程序的内部启动另一个程序,从而创建一个新进程。system函数需要的头文件为:#include<stdlib.h>,函数原型为:

int  system(const char *string);

string是包含了命令的字符串,该函数能执行命令。

测试代码:

#include<stdio.h>
#include<stdlib.h>

int main(void)
{
	system("pwd");
	system(" ls -l");
	printf("OK!\n");

	return 0;
}

运行结果:

可以看到该程序成功打印了当前工作目录和目录下的文件,因此,借助system函数我们能很方便的执行命令行程序。

6.应用示例

设已有一个hello.c程序,该程序输出“hello,world!”,现在编写一个程序来编译该源程序,编译完成后执行该程序。

示例代码:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>

int main(void)
{
   system("gcc hello.c -o hello");
   printf("hello.c compile sucessfully!\n");
   if(fork()==0)
   {
	   if(execlp("./hello","hello",NULL)<0)
	   {
		printf("execlp error!\n");
	   }
   }
   sleep(1);
   printf("Hello run successfully!\n");
    return 0;
}

运行结果:

 

 

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值