Linux进程学习:初窥门径

前言:周末起来打开手机,开启一天的冲浪生活,等了一夜的女神聊天框只有一个晚安;于是你点开美团决定给她送点吃的,一会之后外卖小哥问你是不是点错了,对面是个男的。是啊,人类社会总是充满了不确定,明天说不定就中彩票了~
计算机就不一样,因为它充满了BUG…

1. 什么是进程

字面意义:正在进行的一个过程。
哈哈,是不是很简单,就像吃饭一样,你是执行这个进程动作的机器;转换视角到计算机则变成了CPU是一个进程的执行者~
show code!
(Linux通过以下指令可以进行当前系统进程打印)

ps axu

笔者机器运行部分结果
笔者机器运行结果图1

看起来很不知所云对不对?但是就是这些进程和OS一起撑起了软件世界的精彩!现在不理解没关系,慢慢来,笔者会慢慢带大家了解这个世界的!

2. Linux第一个进程

通过上面的shell指令我们可以了解到,Linux系统上运行着各种各样的进程,面对这些形形色色的进程我们忍不住问出那个灵魂问题:谁是第一个进程?
也许有信仰上帝的人会说:Computer God.
也许有信仰马圣的人会说:第一个物质进程.
。。。。。。
不卖关子了,其实,Linux第一个进程很佛系, 称IDLE(不是Python那个开发环境哈),真正的0号,
当它被内核运行之后,它也非常符合名字(懒)的直接放权让init进程去干活了(具体的活暂不展开)~
然后就是道教有名的道生一,一生万物理论(老子要是现代人估计是个计算机进程领域大拿)
Linux进程按照上面的描述形式就形成了一颗进程树

进程树图2

3. 向传统C程序 say byebye

理论聊了半天,应该上正菜了:写一个简单的多进程程序!
先看今天的食材:

#include  <unistd.h>
pid_t fork( void);

fork系统调用用于创建一个新进程,称为子进程,它与原进程(称为系统调用fork的进程)同时运行,此进程称为父进程。

#include <unistd.h>
int execve(const char *filename, char *const argv[],  char *const envp[]);

execve函数可以使进程能够以全新程序来替换当前运行的程序。再次过程中,将丢弃旧有程序,进程的栈.数据以及堆段会被新程序所替换。

4. 生子当如parent – fork

一个进程可以调用fork函数创建一个新进程。由fork创建的新进程被称为子进程(child process)。fork函数被调用一次但返回两次(唯一区别是子进程中返回0,父进程中返回子进程ID),事情开始魔幻了~
通过fork的子进程是父进程的副本,BUT,父子进程间不共享这些存储空间。

第一个简单的程序

#include  <stdio.h>
#include  <unistd.h>

static int  s_val = 0;

int main()
{
    int pid = 0;

	if ( (pid = fork()) > 0 ) {
		s_val = 7;
	    printf("parent: s_val: %d\n", s_val);

	} else {
		s_val = 9;
	    printf("child:  s_val: %d\n", s_val);

	}

	return 0;
}

do it,可以猜猜看会发输出什么~

5. 彼可取之current – execve()

进程在执行execve族的函数之后,会把代码段替换成新程序的代码,放弃原有的数据段和堆栈段,并为新程序分配新的数据段与堆栈段,惟一保留的就是进程的 ID。也就是说,对系统而言,还是同一个进程,不过执行的已经是另外一个程序了(彼可取而代之!)

这个实验需要,两个文件,hello.c main.c

//hello.c 需要编译成hello.out
#include  <stdio.h>
#include  <unistd.h>

int main()
{
	printf("pid = %d; hello world!\n", getpid());
	return 0;
}

//main.c 输出 main.out
#include  <stdio.h>
#include  <unistd.h>

#define   process_name     "hello.out"

int  create_new_process(const char* name, char* const argv[])
{
    int ret = fork();

    if ( !ret ) {
		execve(name, argv, NULL);
	}

	return ret;
}

int main()
{
	char* const  process_avg[] = {"hello.out", NULL};
	
    printf("pid = %d\n", getpid());

	printf("child = %d\n", create_new_process(process_name, process_avg) );

	printf("end.\n");

	return 0;

执行main.out,分析代码执行结果,可以发现,子进程execve之后不会再返回执行副本代码,而是被替换成了hello.out,有点杜鹃鸟的属性~

看文千篇不如动手一练,希望读者可以好好实验,一起探索Linux程序设计!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值