Linux进程2

进程

初步理解进程

A进程创建了B进程,则A叫做B的父进程,B是A的子进程,而在进程创建过程中,OS内核一般会把父进程的地址空间拷贝一份给子进程,这样父子进程之间的任何操作都不会影响对方,即他们的资源是独立的。但为了节省资源,常常会用到引用计数,这样就可以使父子进程在读时共用一份相同的资源,而当其中一方要进行写时,才会拷贝要修改的那部分资源。

而在代码上,进程是由一个结构体描述的,即PCB(在Linux中是task_struct),这样把所有进程都放在一个数据结构中,就可以统一的进行管理。

进程状态
  1. R运行状态(running): 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列

里。

  1. S睡眠状态(sleeping): 意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠

(interruptible sleep))。

  1. D磁盘休眠状态(Disk sleep)有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的

进程通常会等待IO的结束。

  1. T停止状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可

以通过发送 SIGCONT 信号让进程继续运行。

  1. X死亡状态(dead):这个状态只是一个返回状态,你不会在任务列表里看到这个状态

我们操作系统往往存在多个进程,这些进程可以近似并行,就行我们可以后台打开音乐听着歌,前台写着代码,而之所以进程能够并行,是因为每个进程都运行一个时间片的时间,然后立马切换到下一个进程,而这个时间片十分短,所以可以达到近似并行的状态。

而在这个过程中,管理进程的主要是两个队列。OS内核有两个指针active指针和expired指针,active指向一个活动队列,其中都是活动的进程,而expired指向的过期队列都是由是时间片耗尽的进程组成,即活动队列的进程时间片耗尽后,如果还有任务,都会进入过期队列,当活动队列为空时,交换活动队列和过期队列。

进程操作

创建进程
#include <unistd.h>

pid_t fork(void);

//返回值:自进程中返回0,父进程返回子进程id,出错返回-1

int main()
{
    pid_t pid = fork();
    if(pid>0)
    {
        //子进程代码
        xxxxxxx
        return 0;
    }
    //父进程代码
	xxxxxxxx
	return 0;
}
进程等待

子进程退出,父进程如果不管不顾,就可能造成‘僵尸进程’的问题,进而造成内存泄漏,因此需要父进程等待子进程退出。

#include<sys/types.h>
#include<sys/wait.h>

pid_t wait(int* status);
//返回值: 成功返回被等待进程pid,失败返回-1。
//参数: 输出型参数,获取子进程退出状态,不关心则可以设置成为NULL


pid_ t waitpid(pid_t pid, int *status, int options);
//返回值:当正常返回的时候waitpid返回收集到的子进程的进程ID;
如果设置了选项WNOHANG,而调用中waitpid发现没有已退出的子进程可收集,则返回0;
如果调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在;
//参数:
    //pid:
        Pid=-1,等待任一个子进程。与wait等效。
        Pid>0.等待其进程ID与pid相等的子进程。
    //status:
        WIFEXITED(status): 若为正常终止子进程返回的状态,则为真。(查看进程是否是正常退出)
        WEXITSTATUS(status): 若WIFEXITED非零,提取子进程退出码。(查看进程的退出码)
    //options:
        WNOHANG: 若pid指定的子进程没有结束,则waitpid()函数返回0,不予以等待。若正常结束,则返回该子进程的ID。
    

退出状态 (status)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

基础替换

fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数

以执行另一个程序。当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。调用exec并不创建新进程,所以调用exec前后该进程的id并未改变。

####  #include <unistd.h>

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 execvpe(const char *file, char *const argv[], char *const envp[]);
  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值