基于Linux的C语言

目录

一,多进程

二,Linux的进程

        1,进程的创建 fork

        2,结束进程:

                2.1,exit  结束当前执⾏的进程,若使⽤标准io,在结束时就会刷新缓冲区(会写⼊⽂件)

                2.2,_exit   结束当前执⾏的进程,但是不会刷新缓冲区。

         3,等待子进程结束

                3.1,wait  使⽤该函数,使进程阻塞(等待),直到任意⼀个⼦进程结束,才继续执⾏。

                 3.2,waitpid功能和wait函数类似,但是waitpid是可以等待指定⼦进程结束

 三,Linux的守护进程

        1,守护进程的基本概念        

        2, 创建⼦进程,⽗进程退出

        3,在⼦进程中创建新会话

               3.1, setsid函数:setsid函数用于创建一个新的会话,并担任该会话组的组长。

                3.2,设置守护进程的⼯作⽬录

              3.3,重设⽂件权限掩码

              3.4,关闭已经打开的⽂件描述符

        4,进程执⾏的命令⾏参数


 

一,多进程

        程序:磁盘上的有序集合

        进程:一个程序执行的过程

        多进程:操作系统能够同时支持多个处理器的能力。

        linux下进程的结构:

                数据段:全局变量,常量以及动态分配的空间(malloc)。

                正文段:程序中的代码。

                堆栈段:局部变量,函数的形式参数,函数返回值。

        进程号:linux对执行程序进行编号(PID)

        调度进程:

                ps:查看当前执行的进程。(ps ax /  axu)。当执行ctr + c的命令后进程截至。

                top:动态显示系统的进程。(按q退出进程)

                kill:向进程发送信号。命令:kill + 需要发送的信号 +  pid(默认发送进程结束信号)

                bg:将挂起的进程在后台运行,命令:bg + pid

                fg:把后台运行的进程放在前台执行,命令:fg +pid

                程序名 + &:表示将程序在后台运行,例如:./a.out +&.

        进程的运行状态:

                运行态:当前进程正在运行或者准备运行(只要获取cpu时间就能运行)进程当前占有CPU,并在在CPU上运行。

                等待态:当前进程正在等待一个事件的产生或者某个系统资源,它分为两种

                        可中断:即使其等待的某特定事件没有发生,可中断休眠状态的进程也可以被唤醒

                        不可中断:必须等到某特定事件发生后才能被唤醒

                停止态:当前进程被停止。

                僵尸态:进程被终止,但资源没有被完全释放。

二,Linux的进程

        Linux进程的创建,是由另一个进程来帮助创建并执行当前这个程序。完成创建的叫父进程,被创建的叫子进程。

        1,进程的创建 fork

        通过当前执⾏的进程(程序),去创建⼀个新的进程,被创建的进程叫做⼦进程,执⾏创建的这个进程叫做⽗进程。当调⽤fork时,会把⽗进程所有资源(代码,变量,打开的⽂件等),复制⼀份给⼦进程(⼦进程的内存空间中内容是和⽗进程完全⼀致)。⼦进程执⾏⾃⼰的内存空间内容---->⼦进程拷⻉⽗进程的所有内容----->然后从fork的返回值开始执⾏.

//头文件
#include <sys/types.h>
#include <unistd.h>
//格式
pid_t fork(void);

返回值:
    成功:在⽗进程中fork的返回值为⼦进程的pid;在⼦进程中fork的返回值为0
    失败:⽗进程返回-1,没有⼦进程

        举例说明:

         父子进程的分别打印

 

        2,结束进程:

                2.1,exit  结束当前执⾏的进程,若使⽤标准io,在结束时就会刷新缓冲区(会写⼊⽂件)

#include <stdlib.h>

void exit(int status);

/*
参数:
    int status:整数,& 0xff,即 只保留低8位⾼位全部清0,作为进程的结束状态,返回给⽗进程
*/

                2.2,_exit   结束当前执⾏的进程,但是不会刷新缓冲区。

#include <unistd.h>

void _exit(int status);

exit 和 _exit的举例说明:


        在C程序,程序只会执⾏main函数中的内容,在main函数中:return语句---结束当前函数(跳出当前函数),结束main函数,结束当前进程。

        举例说明:

         3,等待子进程结束

                3.1,wait  使⽤该函数,使进程阻塞(等待),直到任意⼀个⼦进程结束,才继续执⾏。

#include <sys/types.h>
#include <sys/wait.h>

pid_t wait(int *wstatus);
/*
参数:
    int *wstatus:指针,变量地址,⽤于存储⼦进程结束状态值的地址
返回值:
    成功:返回阻塞等待到的结束的⼦进程的pid
    失败:返回-1
*/

               举例说明:

                 3.2,waitpid功能和wait函数类似,但是waitpid是可以等待指定⼦进程结束

#include <sys/types.h>
#include <sys/wait.h>

pid_t waitpid(pid_t pid, int *wstatus, int options);
/*
参数1:
    pid_t pid:进程号
    pid > 0:只等待进程id等于pid的⼦进程
    pid == -1:等待任何⼀个⼦进程结束,作⽤和wait⼀样
    pid < -1:等待其进程组等于pid的绝对值的任意⼦进程
    pid == 0:等待其进程组id等于调⽤进程的组id的任意⼦进程
参数2:
    int *wstatus:同wait,等待接收⼦进程的状态值
参数3:
    int options:
选项     0:同wait,表⽰阻塞,⼀直等待⼦进程结束
        WNOHANG:表⽰不会阻塞等待。若,对应pid的⼦进程现在没有结束,则不等待⼦进程结束,当前函数直接返回,若调⽤时对应pid的⼦进程已经结束,则回收得到⼦进程状态,当前函数直接返回。
返回值:
    成功:返回阻塞等待到的结束的⼦进程的pid
    失败:返回-1
*/

               举例说明 

 三,Linux的守护进程

        1,守护进程的基本概念        

        守护进程:是Linux中的后台服务进程。它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。守护进程常常在系统引导装入时启动,在系统关闭时终止。Linux系统有很多守护进程,大多数服务都是通过守护进程实现的,同时,守护进程还能完成许多系统任务。通常也称之为Daemon进程。

        实现守护进程:由于在Linux中,每一个系统与用户进行交流的界面称为终端,每一个从此终端开始运行的进程都会依附于这个终端,这个终端就称为这些进程的控制终端,当控制终端被关闭时,相应的进程都会自动关闭。但是守护进程却能够突破这种限制,它从被执行开始运转,直到整个系统关闭时才退出。如果想让某个进程不因为用户或终端或其他地变化而受到影响,那么就必须把这个进程变成一个守护进程。

        2, 创建⼦进程,⽗进程退出

        由于守护进程是脱离控制终端的,因此,完成第一步后就会在Shell终端里造成一程序已经运行完毕的假象。之后的所有工作都在子进程中完成,而用户在Shell终端里则可以执行其他命令,从而在形式上做到了与控制终端的脱离。

        在Linux中由于父进程先于子进程退出,所以造成子进程成为孤儿进程。

        举例说明:

        3,在⼦进程中创建新会话

        进程组:是一个或多个进程的集合。进程组有进程组ID来唯一标识。每个进程组都有一个组长进程,其组长进程的进程号等于进程组ID。且该进程组ID不会因组长进程的退出而受到影响。

        会话:会话期是一个或多个进程组的集合。

        流程图:

 

               3.1, setsid函数:setsid函数用于创建一个新的会话,并担任该会话组的组长。

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

pid_t setsid(void);

                3.2,设置守护进程的⼯作⽬录

        在创建子进程时,子进程继承了父进程的工作路径,为了不造成不必要的麻烦,我们有必要为子进程设置一个自己的工作路径。

#include <unistd.h>

 int chdir(const char *path);
/*
 参数1:
     const char *path:新的⼯作路。
*/

              3.3,重设⽂件权限掩码

        文件权限掩码是指屏蔽掉文件权限中的对应位。子进程不仅继承了父进程的工作路径还继承了父进程的文件权限掩码,为了避免不必要的麻烦,我们有必要重设子进程的文件掩码,我们通常把⽂件权限掩码设置为0,这样可以有效的增加该守护进程的灵活。

#include <sys/types.h>
#include <sys/stat.h>

mode_t umask(mode_t mask);
/*
参数:
    mode_t mask:新的文件权限掩码。
*/

              3.4,关闭已经打开的⽂件描述符

        子进程继承了父进程的已经打开的文件,这些文件可能不会被守护进程读写,没有任何价值,这样就会造成资源浪费。所以应该关闭这些用不到的文件。

#include <unistd.h>

 int getdtablesize(void);

        4,进程执⾏的命令⾏参数

        在执⾏程序时,除了有要执⾏的程序,还可以加上参数。

        参数是添加到执⾏的程序中------>执⾏main函数。

        main函数有参数列表,⽤于在执⾏程序时接收参数。

int main(int argc,char * argv[])
/*
参数:
    argc:表⽰执⾏的命令⾏有多少个参数(包括程序名)
    argv:指针数组,数组的每⼀个元素是⼀个指针(char *),数组每⼀个元素就是⼀个字符串的⾸地址,字符串就是命令⾏上的参数
*/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值