Linux进程介绍

      进程管理着资源(比如cpu、内存、文件等等),而将线程分配到某个cpu上执行。在操作系统设计上,从进程演化出线程,最主要的目的就是更好的支持多处理器系统和减小上下文切换开销。
       进程是资源管理的基本单位。 系统使用进程控制块(PCB Process Control Block)来描述进程的资源,它是进程实体的一部分,是操作系统中最重要的记录性数据结构。
       在Linux 内核中,进程控制块是由struct task_struct 结构体表示的。此结构包含所有表示此进程所必需的数据,此外,还包含了大量的其他数据用来统计和维护与其他进程的关系(父和子)。task_struct 位于 ./linux/include/linux/sched.h。

一、进程状态
     在Linux 2.6内核中,用户级进程的状态比较容易理解,值得注意的是 UNINTERRUPTIBLE 及 ZOMBIE。
TASK_RUNNING:就绪/运行状态。
TASK_INTERRUPTIBLE:等待状态(可被中断唤醒)。处于等待队列中,等待资源有效时唤醒,可以被中断唤醒。
TASK_UNINTERRUPTIBLE:等待状态(不可被中断唤醒)。处于等待队列中,等待资源有效时唤醒,可以被中断唤醒。此时进程不接收信号,这就是                                                  为什么有时候kill一个繁忙的进程没有响应。
TASK_ZOMBIE:僵死状态。我们经常 kill -9 pid 之后运行ps会发现被kill的进程仍然存在,状态为 zombie。zombie的进程实际上已经结束,占用的资                             源也已经释放,仅由于kernel的相关进程描述符还未释放。
TASK_STOPPED:停止状态。进程被外部程序暂停的状态。如收到SIGSTOP信号,当再次允许时,再次执行,如接到SIGCONT信号。所以,这一状                                态是可以被唤醒的。



二、进程的基本属性
1、进程号(PID)
      OS会为每个进程分配唯一的整型ID,作为进程的进程号(PID)。 进程0为调度程序,是内核的一部分,也被成为系统进程。 进程1是init进程,是内核第一个启动的进程,负责引导系统,启动守护进程并运行必要的程序,它不是系统进程。
      使用getpid()函数来获得进程的PID。函数返回值为进程号,类型是pid_t。pid_t就是int类型。例如:
#include<unistd.h>
#include<stdio.h>
int main()
{
  printf(“pid=%d\n”,getpid());
}
2、父进程号(PPID)
      任何一个进程都是由其他进程创建的,该进程称为被创建进程的父进程。
      使用getppid()函数获取父进程。   
     
3、组进程号(PGID)
      
三、相关函数
1、fork()    功能:创建一个新的进程
语法:
#include <unistd.h> 
#include <sys/types.h> 
pid_t fork(); 
(1)说明:
         产生一个新的进程,  叫子进程,  是调用进程的一个复制品.  调用进程叫父进程,  子进程继承了父进程的几乎所有的属性(代码段、数据段、堆栈)。      
         fork()以后,父、子进程共享代码段。
(2)简述:fork() 调用成功时,分别返回两个整数,对父进程返回 大于0 的整数,对子进程返回0。
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
int main(void)
{
	printf("fork test!\n");	
		
	pid_t pid;
	if((pid=fork())==-1)
		printf("fork error");
	else if(pid==0)
	{
		printf("in the child process\n");
		printf("the father process's ppid is %d\n",getppid());
	
	}
	else
	{
		printf("in the parent process\n");
		printf("the son process's pid is %d\n",getpid());
	}
	return 0;
}
注:
a、子程序的知性位置是fork()函数的返回位置
b、父进程先执行,子进程后执行(ubuntu12.04)


2、exec()函数簇
功能:执行一个文件
语法:
#include <unistd.h>
int execve(const char* path, char* const* argv,char* const* envp);
int execl(const char* path, char* arg,...); 
int execp(const char* file, char* arg,...); 
int execle(const char* path, const char* argv,...,char* const* envp);
int execv(const char* path, char* const* arg); 
int execvp(const char* file, char* const* arg);
fork()以后,父、子进程共享代码段,并只重新创建数据有改变的页(段页式管理)。
exec()以后,建立新的代码段,用被调用程序的内容填充。
前者的子进程执行后续的公共代码,后者的子进程不执行后续的公共代码。
#include <stdio.h>
#include <unistd.h>
int main()
{
execve("./helloworld",NULL,NULL);
printf("nothing!\n");
return 0;
}
这个程序输出什么?(假设helloworld程序输出hello world!)
那么,这个程序输出的,就是hello world!
你会想,为什么没有下面的nothing!啊?
因为,execve调用中,这些代码都没有了,代码被替换成helloworld的了,而且,只执行helloworld就完了!

3、wait()    

功能:使父进程暂停执行,等待一个子进程返回并修改状态 

语法:    

#include <sys/types.h> 
#include <sys/wait.h> 
pid_t wait(stat_loc) 
int *stat_loc; 
说明: 允许调用进程取得子进程的状态信息.调用进程将会挂起直到其一个子进程终止. 
返回值: 等待到一个子进程返回时,返回值为该子进程号,否则返回值为 -1.同时 stat_loc 返回子进程的返回值。

waitpid()    
功能:等待指 定进程号的子进程 的返回并修改状态 
语法:
#include <sys/types.h> 
#include <sys/wait.h> 
pid_t waitpid(pid,stat_loc,options) 
pid_t pid; 
int *stat_loc,options; 
说明:当 pid 等于-1,options 等于 0 时,该系统调用等同于 wait().否则该 系统调用的行为由参数 pid 和 options 决定
pid 指定了一组父进程要求知道其状态的子进程: 
-1:要求知道任何一个子进程的返回状态. 
>0:要求知道进程号为 pid 值的子进程的状态. 
<-1:要求知道进程组号为 pid 的绝对值的子进程的状态. 


4、system()    
功能:产生一个新的进程,  子进程执行指定的命令. 
语法:


#include <stdio.h> 
#include <stdlib.h> 
int system(string) 
char *string; 
#include <stdio.h>
#include <unistd.h>
int main()
{
ret=system("./helloworld",NULL,NULL);
printf("返回值:%d\n",ret);
return 0;
}
这个程序输出什么?(假设helloworld程序输出hello world!)
那么,这个程序输出的,就 hello world!
返回值:0


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值