当前位置: 首页 > Linux kernrl, 进程/线程 > 正文

linux进程控制

                                                linux   进程控制  1

首先,linux是一个多任务多进程的操作系统,所以必须要讨论进程的控制。

进程:

进程是一个动态的实体,是程序的一次执行过程,它是操作系统的资源分配的基本单位,简单来说线程和进程区别不大,一个主要的区别就是进程有自己的内存空间,并且占用系统资源。

进程标识:进程的一个重要的标识就是其进程的ID ,PID。

    一般使用如下的一些函数来获取ID ,

getpid( )                  获得进程的PID

getppid( )                获得父进程的PID

getuid( )                  获得实际用户ID

geteuid( )                获得有效ID

getgid( )                  获得实际的组ID

getegid( )                获得有效的组ID

进程的状态:

运行状态:正在运行或者等待运行

可中断等待状态:进程正在等待某个事件完成,等待过程就可以被信号或者定时器唤醒

不可中断等待状态:同上但是不能被唤醒,只有在等待的时间完成后,才可以继续进行

僵死状态:进程已经终止,但描述符还存在,直到父进程调用WAIT( )函数释放‘

停止状态:进程因为受到了指示结束或暂停的信号,停止运行。

进程的一些状态标示:

<   :高优先级

N   :低优先级

L    :内存页面不可换出

S   :首进程

I     :多线程进程

+    : 进程为于前台进程组

进程的控制函数:

fork;  用于创建一个进程

exit:   用于终止进程

exec: 用于执行一个应用程序

wait: 将父进程挂起,等待子进程终止

getpid:获取当前进程的ID

nice:   更改进程的优先级

创建一个进程:

创建一个进程的方式一般有两种:

1。由操作系统创建

      2.   由父进程创建

fork( ) 函数是创建一个新进程的唯一方法(init进程是由内核创建)

此函数一般有两个返回值:

1.一个返回值为0,这是子进程fork( )返回的值,为0,标示成功创建

2.另一个值为PID ,表示子进程的ID 。


这个程序就是使用fock 函数创建一个进程然后返回父进程的ID 和子进程的ID。


一般来说,创建进程之后是父进程先执行还是子进程先执行是不确定的,这个顺序取决于当下使用系统的调度算法。

子进程一般会继承父进程的很多属性:

用户ID,组ID,当前工作目录,根目录,打开的文件,创建文件时使用的屏蔽字,信号屏蔽字,上下文环境,共享的存储段,资源限制等。

同时他们二者还有不同的属性:

进程有它自己的唯一的进程ID。

fork( )的返回值不同,父进程返回子进程的ID ,子进程返回0

每一个子进程的ID 只能是创建他的父进程所给的ID 。

子进程共享父进程的打开的文件描述符,但父进程对文件描述符的改变不会影响子进程中的文件描述符。

子进程不继承父进程的设置的文件锁

子进程不继承父进程的警告

子进程的未决信号集被清空

孤儿进程:

当一个父进程死亡后,他的子进程就变成了孤儿进程,且被init进程收养

vfork( ) 函数与 fork( )函数的比较

1。都是创建一次返回两次,因为前者实际上是调用了后者

2。后者完全复制父进程的资源与地址等,有良好的并发性,后者是共享地址空间与资源

3。前者保证首先运行子进程,当使用了exec,exit 时父进程才会被调用,如果在这些调用之前需要使用父进程就会导致死锁。

死锁:

所谓死锁: 是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程

发生死锁有4个产生条件;

1)互斥条件:指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。如果此时还有其它进程请求资源,则请求者只能等待,直至占有资源的进程用毕释放。
2)请求和保持条件:指进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放。
3)不剥夺条件:指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。
4)环路等待条件:指在发生死锁时,必然存在一个进程——资源的环形链,即进程集合{P0,P1,P2,···,Pn}中的P0正在等待一个P1占用的资源;P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源。
守护进程:
守护进程就是在后台运行的进程,他不占用终端,一般用来执行固定的一些任务。
创建一个守护进程的步骤:

(1)在父进程中执行fork并exit推出;

(2)在子进程中调用setsid函数创建新的会话;

(3)在子进程中调用chdir函数,让根目录 ”/” 成为子进程的工作目录;

(4)在子进程中调用umask函数,设置进程的umask为0;

(5)在子进程中关闭任何不需要的文件描述符

#include
#include


这个程序用来创建一个守护进程,然后这个进程每隔一秒就删除

这两个文件(这是不停生成的日志文件,同理用守护进程不同的生成这两个文件)


进程退出正常退出方法有两种,异常退出方法有三种:

1.正常退出

return退出

调用exit( ) 函数退出

调用_exit( )函数退出

2.异常退出

调用abort( )函数退出

进程收到某个信号自动退出

各种退出方式的比较:

exit( )    , return:前者时函数,接受参数,返回后将控制权限交给系统

    后者返回将控制权限交给,调用函数

exit( ) , abort( ):   前者是正常退出,后者是异常退出

exit(exit_code):   参数为0代表正常退出,参数不为0,代表有错误发生

exit( ) ,_exit( ):     两者不再同一个头文件里,后者执行后立即返回给内核,前者需要执行一系列的清除操作,然后将控制权交给内核。

执行新的进程:

       #include
       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 execvpe(const char *file, char *const argv[],
                   char *const envp[]); 这是
exec一族的全部函数。

execv:此函数通过调用路径名的方式调用可执行文件作为新的进程映像,后面的参数就是命令行参数

   execve:此系统调用参数是路径名,后便的参数和main( )函数是对应的

       #include
       #include
       pid_t wait(int *status);
       pid_t waitpid(pid_t pid, int *status, int options);

wait( )函数就是等待进程结束他的接受值用来存放进程的退出码。

改变进程的优先级,

#include
       int nice(int inc);

他的参数就指定的优先级的数值;

一个示例程序,其中getproiority 是获得当下进程优先级的函数.

版权声明:本文为博主原创文章,未经博主允许不得转载。

]]>

本文固定链接: http://zmrlinux.com/2015/06/01/linux%e8%bf%9b%e7%a8%8b%e6%8e%a7%e5%88%b6/ | Kernel & Me

该日志由 root 于2015年06月01日发表在 Linux kernrl, 进程/线程 分类下, 你可以发表评论,并在保留原文地址及作者的情况下引用到你的网站或博客。
原创文章转载请注明: linux进程控制 | Kernel & Me
【上一篇】
【下一篇】