Linux 进程心得

查看进程号:ps -ef

查看某个进程信息:ps -ef grep 进程号

查看进程树:pstree

杀死进程:kill -9 进程号(-9的意思是强制执行)

main函数

在C语言中,main函数的标准原型是:

int main(int argc, char const *argv[])

int:这是main函数的返回类型,表示函数返回一个整数类型的值作为程序的退出状态码。
main:这是程序的入口函数,是程序开始执行的地方。
argc:这是一个整数参数,表示命令行参数的数量。在运行程序时,命令行输入的参数个数会被计数,至少为1(即程序名本身)
char const *argv[]:可以将程序从命令行传递进来的参数,通过管道传输给子进程。(但是argc必须大于2,因为程序本身是第一个参数)

在运行一个C程序时,可以通过命令行向程序传递参数。例如,如果你有一个名为program.exe的可执行文件,并希望向其传递参数,可以这样做:
program.exe arg1 arg2 arg3

argc将会是 4,因为包括程序名本身和三个参数。
argv[0]将是指向程序名"program.exe"的字符串的指针(程序的路径)。
argv[1] 将是指向字符串"arg1"`的指针。
argv[2]将是指向字符串"arg2"`的指针。
argv[3]将是指向字符串"arg3"`的指针。
argv[4]将是 `NULL`,标志参数数组的结束。

因此,main函数的标准原型允许我们通过argc和argv参数来接收和处理命令行输入的参数。

fork

#include<unistd.h>
#include<stdio.h>
#include<sys/types.h>

int main(){
/*调用fork之前,代码都在父进程运行*/
printf("海哥教老学员%d \n",getpid());

/*使用fork创建子进程,父进程和子进程各执行一遍
*如果成功运行,返回两个值:
* (1) 在父进程中 返回子进程的 PID
* (2) 在子进程中 返回 0
* 如果发生错误 返回-1*/
pid_t pid=fork();

if(pid==0){/*执行单独子进程*/
    printf("新学员 %d 加入成功,他是老学员%d 推荐的\n",getpid(),getppid());/* 返回该进程的 pid;返回该进程父进程的 pid*/
}

else if(pid>0){/*执行单独父进程*/
    printf("老学员%d 继续深造,他推荐了%d\n",getpid(),pid);/* 返回该进程的 pid;父进程中的pid表示的是子进程号*/
}

else if(pid<0)   perror("进程出错:");

return 0;
}

execve

execve本质就是让一个进程跳转去执行另一个进程。
char *new_name="lcx";
char *argv[]={"/home/lcx/PROCESS_TEST/erlou",new_name,NULL};
/*要跳转到的可执行文件路径、传入的参数、最后一个参数必须是 NULL*/
char*envp[]="PATH=...",NULL};
/*环境变量参数echo $PATH、最后一个参数必须是 NULL*/

execve(argv[0],argv,envp);

waitpid

父进程一定要等子进程运行结束后去回收他。

  • 孤儿进程是指父进程先于子进程结束,子进程成为孤儿,由内核接管,并由他给自己的祖先领养。
  • 僵尸进程是指一个进程已经结束运行,但父进程没有及时释放掉他,进程描述符依然留在进程表中。

如果是父进程等待子进程执行的场景:

sleep(1):可以使用等待一秒(不推荐);

waitpid(pid,NULL,0):执行之后将会一直挂起父进程(调用者) 的执行,直至子进程 pid 终止(推荐)。

进程树

输入命令 pstree -p                    查看进程数

输入命令 ps -ef                         查看所有进程

输入命令 ps -ef | grep 进程号   查看指定进程号

进程通信

socket

可以实现不同主机进程的全双工通信。

管道

  • 优点
    • 简单易用,是最基本的进程间通信方式之一,通过内核缓存区来通信。
    • 实现简单,通常由操作系统来管理。
    • 适合用于父子进程或者兄弟进程之间的通信。
  • 缺点
    • 匿名只能在有血缘关系的进程之间使用,即父子进程或兄弟进程。
    • 单工通信模式,想要实现半双工通信必须再开启一个管道
    • 数据量有限,通常只能传输有限长度的数据。

匿名管道

进程结束时自动销毁;

用于父子进程或者兄弟进程之间的单向通信;

有名管道

通常持久存在,直到显式删除它们为止;

有名管道有一个路径名,多个无关的进程之间可以通过在文件系统中的路径来访问和使用;

共享内存

  • 优点
    • 提供了速度最快的进程间通信方式,因为多个进程可以直接访问同一块内存区域。
    • 可以传输大量数据,效率高。
    • 可以通过内存映射文件实现跨越无关进程的共享
  • 缺点
    • 需要额外的同步机制来避免多个进程同时修改共享内存造成的数据不一致问题。
    • 不提供同步和互斥机制,需要额外的信号量等机制来控制进程对共享内存的访问。
    • 不适合于分布式系统中的进程通信。

消息队列

  • 优点
    • 提供了异步通信的方式,发送方和接收方可以独立操作。不需要同步操作即使接收进程当前不可用也能保证消息的传递。程序并发性高
    • 可以支持复杂的数据结构和大量的数据
    • 可以实现优先级消息,消息队列支持消息的选择性接收。
  • 缺点
    • 实现较为复杂,通常需要额外的系统调用,通信不及时
    • 可能会引入额外的系统开销,特别是在消息较多或消息量大的情况下。

父子进程消息队列

通常用于同一主机上的进程间通信,涉及到父子进程关系

生产者消费者消息队列

通常用于不同进程之间的进程间通信(IPC)

信号量

二进制信号:
或称作 互斥锁 ):其值只能是 0 1 ,主要用于实现互斥,即一次只允许一个线程进入 临界区 。通常用于控制共享资源的访问,避免竞态条件的产生。
计数信号量:
其值可以是任意非负整数,表示可用资源的数量。计数信号量通常用于 控制不同进程或线程执行的顺序 ,如消费者必须在生产者发送数据后才可以消费。

  • 19
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值