3、进程(李慧琴课程笔记)

本文详细介绍了Linux进程的基本概念,如进程号、fork操作、init进程、ps命令、用户组权限、shell脚本、进程时间和守护进程的特性,以及exec函数族和系统日志的相关知识。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

3、进程

3.1 进程

3.1.1 进程号是按顺序取的,而不是取最小值

/*获取子进程*/
getpid();
/*获取父进程*/
getppid();

3.1.2 fork创建一个新进程

创建的子进程和父进程执行的位置都一样,意味着拷贝、克隆的含义
fork返回值不一样,pid不同、ppid不同、未决信号和文件锁不继承,资源利用量清0

3.1.3 init进程:1号,是所有进程的祖先进程

永远不要凭空猜测哪一个进程先运行

3.1.4 ps axf 可以查看进程的阶梯关系

在fork前一定要加上fflush(NULL)刷新流操作

因为printf类似于全缓冲,\n只代表换行的作用,而不代表刷新的作用了,当第一次printf时Begin还未来得及写入文件时就创建了子进程,因此会有两个Begin。终端上可能只显示一个,但是当./fork > /tmp/out时会输出两个Begin!

printf("[%d]:Begin\n",getpid());
fflush(NULL);/*很重要!!!*/
pid = fork();

fork函数若父子进程同时读一块空间则互不影响,若谁要对同一块空间进行修改,则谁copy一份空间独自对其进行修改

3.1.5 在多进程协作任务时,注意某些子进程需要使用exit(0)以防子进程递归创建导致死机或者资源浪费。

3.1.6 vfork函数使父子进程都使用同一份空间(但此函数基本被弃用)

3.1.7 wait函数

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

wait函数会死等一个进程,属于阻塞状态
waitpid中options可以使其为非阻塞或者阻塞状态
pid>0表示特定的一个pid
pid=0表示收同组的任一子进程
pid=-1表示收任一一个子进程
pid<-1表示从一个进程组收一个pid,此pid为绝对值

3.1.8 进程分配有三种方法

1.分块
2.交叉分配
3.池

3.1.9 exec函数族(一般选execv或者execvp变参更爽)

file或者path为可执行文件
小知识,glob函数也很好用,用man查看即可

1.int ececl(const char *path,const char *arg,...);
2.int ececlp(const char *file,const char *arg,...);
3.int ececle(const char *path,const char *arg,...,const char *envp[]);
4.int ececv(const char *path,const char *argv[]);
5.int ececvp(const char *file,const char *argv[]);

在所有exec函数前必须加fflush(NULL)函数来刷新缓流
如果不加,则输入命令./ex > /tmp/out 和 cat /tmp/out则不会显示Begin!
示例

/*此处头文件省略了嘻嘻嘻*/
int main()
{
	puts("Begin!");

	fllush(NULL);!!!
	execl("/bin/date","date","+%s",NULL);
	perror("execl()");
	exit(1);

	puts("End!");
	exit(0);


}

3.2用户组权限相关知识

+s表示在其他用户调用此二进制可执行文件时,这个文件的身份将会变成被调用可执行文件的user来执行(可能是root等用户)

u+s
g+s
getuid();
geteuid();
getgid();
getegid();
setuid();
setgid();
setreuid(uid_t ruid, uid_t euid);原子化的交换
setregid(gid_t guid, gid_t guid);
seteuid();
setegid();

3.3 解释器(shell脚本)

1.#!是脚本文件标记,只会用!后面指定的解释器装载进来,然后用这个指定的解释器解释所有内容,包括第一行,但是第一行会当注释来看待!

1.#!/bin/bash
用bash解释下面所有内容
ls
whoami
cat /etc/shadow
ps
用cat解释下面所有内容
2.#!/bin/cat

ls
whoami
cat /etc/shadow
ps

3.4 进程时间

times获取进程

clock_t times(struct tms *buf);
struct tms
{
	clock_t tms_utime/*Usr time*/
	clock_t tms_stime/*system time*/
	clock_t tms_cutime/*user time of children*/
	clock_t tms_cstime/*system time of children*/
};
若想知道每一秒多少个滴答数,可以用宏来检测
sysconf(_SC_CLK_TCK);

3.5 守护进程

1.脱离控制终端(用ps axj查看时TTY为?)

2.是一个会话(session,标识为sid)的leader和进程group的leader

3.前台进程组有且只能有一个,可以没有,后台进程组不能有标准输入、标准输出、标准错误,如果有将会被杀死。

4.setsid();创建一个会话(session)
/只能子进程调用,父进程不能调用(因为父进程为组进程leader),调用这个函数的进程会成为当前新的进程组的leader,并且脱离控制终端/

5.父进程为1号进程

6.单实例守护进程:锁文件一般是/var/run/name.pid,使用锁文件使守护进程具有唯一性

7.启动脚本文件(认为控制):/etc/rc…(不同系统会有区别,也是使其具有唯一性)*

pid_t setsid(void);/*只能子进程调用,父进程不能调用*/
pid_t getpgrp(void);/*返回当前进程所在组的id*/
pid_t getpgid(pid_t pid);/*获取某一个process的组id*/
pid_t setpgid(pid_t pid, pid_t pgid);/*设置某一个process的组id*/

3.6 系统日志

/*syslogd服务*/
void openlog(const char *ident, int option, int facility);/*ident一般是我们给出的字段,option一般放LOG_PID,facility不能随便写,课程内是LOG_DAEMON*/
void syslog(int priority, const char *format, ...);/*提交日志相关信息,类似于printf的操作,一般情况下大于LOG_INFO的才会写进去,LOG_DEBUG这样的不会*/
void closelog(void);
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值