linux 系统编程 进程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux 系统编程 进程相关的知识,希望对你有一定的参考价值。

进程

进程号一般不重复使用

空闲进程 pid 0 ,内核运行的第一个进程 init pid 1.

内核搜索init的顺序,如果找不到,内核就会发出panic挂起

/sbin/init

/etc/init

/bin/etc

/bin/sh

 

进程号最大值32768  老unix用16位计算pid,可以在/proc/kernel/pid_max的值修改

 

#include<sys/types.h>

#include<unistd.h>

Pid_t getpid();    //返回调用进程的pid

Pid_t getppid();        //返回调用进程的父进程pid

 

1. Exec

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

 

Path 指向要调用文件的映像,如路径,arg为第一个参数,一般为文件名,后面接可变参数,最后以NULL结尾。

执行完替换之后,原进程所有数据丢失,原进程设置的信号处理函数和挂起的信号丢失,原进程对线程的设置丢失,进程的统计信息丢失。但进程pid等不变。

详细解释:http://blog.csdn.net/lianghe_work/article/details/47704105

 

 

 

 

2. fork()

#include<sys/types.h>

#include<ubistd.h>

Pid_t fork();

         生成一个和父进程几乎一模一样的进程

不同点:

Pid和ppid

子进程资源统计信息会清零

挂起信号和文件锁不会继承

 

 

 

 

3. exit

#include<stdlib.h>

Void exit(int status);

Status 标示退出状态 status & 0377会返回给父进程确认

EXIT_SUCCESS  0  EXIT_FAILURE 非零

关闭流程:

在系统中注册的逆序调用atexit或onexit

清空所有已经打开的标准I/O

删除由tmpfile()创建的所有临时文件

调用_exit让内核处理终止进程剩余工作

内核清理:申请的内存,打开的文件,system V信号

进程可以直接调用_exit,但这样一些进程处理的清理未完成,不合理。只有vfork一定要调用_exit。

其他方式结束进程:

Main函数返回或者调用exit(0)。

SIGTERM 和 SIGKILL被触发

程序段错误或者内存耗尽内核强制杀死

 

4. atexit

#include<stdlib.h>

Int atexit(void (*function) (void));

函数成功返回会将函数注册到进程正常结束的时候调用。

如果进程调用了exec,那么atexit不会被调用,进程被信号结束也不会调用这个函数,被注册的函数应该是无参无返回的,调用顺序和注册顺序相反。

 

进程结束时,内核会给父进程发送信号SIGCHILD,一般这个信号会被忽略。如果有需要可以使用signal或者sigaction处理

 

等待死亡的进程会保留一定的信息等待父进程查看,父进程查看后子进程消亡,如果不查看就会成为僵尸进程

 

5.wait

#include<sys/types.h>

#include<sys/wait.h>

pid_t wait(int *status);

返回已经终止的子进程 status子进程结束的状态

如果没有子进程结束会阻塞

6.waitpid

#include<sys/types.h>

#include<sys/wait.h>

Pid_t waitpid(pid_t pid,int *status,int options);

Pid 取值

-1  pid绝对值的进程组的所有子进程

0 同一进程组的任意进程

>0 指定的子进程的等待

 

Options取值:

WNOHANG  不阻塞

 

实际用户ID 真实的用户ID,无法修改,会在各个地方被继承root可以修改他

有效用户ID     进程使用的用户ID,权限验证使用这个ID,使用setuid可以修改

保存设置的用户ID

文件系统用户ID

 

#include<sys/types.h>

#include<unistd.h>

Int setuid(uid_t uid); //root用户可以设置任意值,非root设置为实际ID和保存ID

Int setgid(gid_t gid);

 

Int seteuid(uid_t euid); //同上

Int setegid(gid_t egid);

 

Int setreuid(uid_t ruid,uid_t euid);

Int setregid(gid_t rgid,gid_t egid);

 

 

守护进程:

  1. fork()创建新的进程,
  2. 在守护进程父进程中调用exit
  3. 调用setsid 使得进程有新的进程组和新的会话
  4. 使用chdir将当前的工作目录改为根目录
  5. 关闭所有的文件描述符
  6. 打开0,1,2文件描述符,重定向到/dev/null。

 

 

 

 

 

线程:

每个线程都有独占的一个虚拟处理器,独自的寄存器组,指令计数器和处理器状态。

同一进程中的线程共享同一的地址空间(动态内存,映射文件,目标代码等等),打开的文件和其他内核资源。

 

让出处理器的系统调用

7.Sched_yield();

#include<sched.h>

Int sched_yield();

中断进程,内核会运行新的进程,但是如果没有其他进程就绪,进程会立马恢复,所以一般这个调用没有太大意义。

 

进程优先级是值越小,优先级越高,开始运行越快,执行时间越长

8.nice

#include<unistd.h>

Int nic(int inc);

成功在现在的优先级上加inc返回新的优先级。只有拥有CAP_SYS_NICE(root)的才能使用负值

由于优先级可以返回负值,所有返回成功失败需要errno测试,在使用前将errno清零

10.getpriority ,setpriority

#include<sys/time.h>

#include<sys/resource.h>

 

Int getpriority(int which,int who) ;

Int setpriority (int which,int who,int prio) ;

Which 取值:

PRIO_PROCESS PRIO_PGRP PRIO_USER

对应的who

进程id,进程组ID,用户id

只有拥有CAP_SYS_NICE(root)的进程才可以降低nice的值,提高优先级

 

 

11.ioprio_get ioprio_set

Int ioprio_get(int which,int who);

Int ioprio_set(int which,int who,int prio);

 

12 .Getlimit setlimit

#include<sys/time.h>

#include<sys/resource.h>

Struct rlimit{

Rlimit_t rlim_cur; //软限制 内核执行的限制

Rlimit_t rlimit_max;//硬限制

}

Int Getlimit(int resource ,struct rlimit *rlim);

Int setlimit(int resource ,const struct rlimit *rlim);

Resource RLIMIT_CUP

不具备CAP_SYS_NICE(root)的进程只能调低硬限制

RLIMIT_FSIZE

RLIMIT_CORE

RLIM_INFINITY

 

名称

意义

RLIMIT_AS

进程总共可用的内存大小的最大值

RLIMIT_CORE

core文件的最大尺寸,如果为0说明不能创建core文件

RLIMIT_CPU

CPU时间的最大值(单位:秒)

RLIMIT_DATA

数据段大小的最大值

RLIMIT_FSIZE

创建文件的大小的最大值

RLIMIT_LOCKS

进程可建立的文件锁的数量的最大值

RLIMIT_MEMLOCK

进程中使用mlock锁定内存的最大尺寸

RLIMIT_NOFILE

进程中文件的打开数量的最大值

RLIMIT_NPROC

每个real user id的子进程数量的最大值

RLIMIT_RSS

最大常驻存储区大小

RLIMIT_SBSIZE

socket缓冲的大小的最大值

RLIMIT_STACK

栈的最大尺寸

RLIMIT_VMEM

=RLIMIT_AS

 

以上是关于linux 系统编程 进程的主要内容,如果未能解决你的问题,请参考以下文章

LINUX系统编程之进程

Linux系统编程——进程调度浅析

Linux系统编程Linux进程管理

Linux系统编程Linux进程调度

Linux编程之《守护进程》

Linux系统编程之进程概念