目录

一、守护进程

        1.概念

                1》守护进程,也就是通常所说的Daemon进程

                2》终端

2,守护进程的原理 

 3.chdir() 改变当前工作目录函数

 3,守护进程创建步骤 

①.第一次的fork

②.在子进程中创建新会话

二、日志系统

1,概念 

    1》打开系统日志 

      2》向日志文件中记录信息 

                3》关闭系统日志    void closelog(void);

    //查看日志中的进程信息

三、文件锁

1,概念 

2,给整个文件上锁 

        flock01.c

        flock02.c

3,给文件的某个区域上锁


一、守护进程

        1.概念

                1》守护进程,也就是通常所说的Daemon进程

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

                2》终端

                //在Linux中,每一个系统与用户进行交流的界面称为终端
        
                //每一个从此终端开始运行的进程都会依附于这个终端,这个终端就称为这些进程的控制终端
        
                //当控制终端被关闭时,相应的进程都会被自动关闭。

2,守护进程的原理 

        一个会话是被一个控制终端控制的,那么若想要创建一个守护进程,必须跳出这个控制终端,由图可以看出想要跳出控制终端的控制范围,就必须要跳出这个会话领域,所以有一下步骤

        1》在原来的会话组进程组中利用p1会话首进程来新建一个新的进程,防止在使用setsid函数的时候把原来的会话进程搞丢

        2》使用新的复制的p2进程利用创建新的会话函数创建一个新的会话组,p2作为新会话组的首进程

        3》在新的会话中,利用p2来创建新的进程组,该进程组我们称为守护进程,因为该进程不会因为控制终端的结束而被KILL掉,他是始终守护在后台,除非调用PS-aux查看详细的进程,进入后再kill掉相关的进程ID。

 3.chdir() 改变当前工作目录函数

        函数原型:int chdir(const char *path );

参数一:指向目录的指针

成功返回

 3,守护进程创建步骤 

①.第一次的fork

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

       由于父进程已经先于子进程退出,会造成子进程没有父进程,从而变成一个孤儿进程。在Linux中,每当系统发现一个孤儿进程,就会自动由1号进程收养。原先的子进程就会变成init进程的子进程。

②.在子进程中创建新会话

        扩展:

        1》进程组

                // 进程组是一个或多个进程的集合。进程组由进程组ID来唯一标识。除了进程号(PID)之外,进程组ID也是一个进程的必备属性之一

                // 每个进程组都有一个组长进程,组长进程的进程号等于进程组ID。

        2》会话期

                // 会话组是一个或多个进程组的集合

                // 通常一个会话开始于用户登录,终止于用户退出,在此期间该用户的所有进程都属于这个会话期

        创建新会话函数:int setsid(void)

        成功返回0,失败返回-1;

        3》创建子进程fork函数

        4》创建完后初始化

        ①关闭所有文件描述符

 sysconf 函数用来获取系统执行的配置信息

        _SC_CHILD_MAX:每个user可同时运行的最大进程数
        _SC_HOST_NAME_MAX:hostname最大长度,需小于_POSIX_HOST_NAME_MAX (255)
        _SC_OPEN_MAX:一个进程可同时打开的文件最大数
        _SC_PAGESIZE:一个page的大小,单位byte
        _SC_PHYS_PAGES:物理内存总page数
        _SC_AVPHYS_PAGES:当前可获得的物理内存page数
        _SC_NPROCESSORS_CONF:配置的处理器个数
        _SC_NPROCESSORS_ONLN:当前可获得的处理器个数
        _SC_CLK_TCK:每秒对应的时钟tick数

        ②消除umask影响,使得该会话中所有文件或目录创建后的默认权限为0

        ③设置守护进程的工作目录,修改目录函数chdir("/");

                参数是目录路径

        ④重定向标准输出,标准输入和标准错误

 void daemon_init(void){pid_t pid;//1,创建子进程if((pid = fork()) < 0){perror("fork");exit(1);}else if(pid > 0)exit(0);//2,创建新会话if(setsid() < 0){perror("setsid");exit(1);}//3,创建子进程if((pid = fork()) < 0){perror("fork");exit(1);}else if(pid > 0)exit(0);//4,关闭所有的文件描述符int i,max_fd = sysconf(_SC_OPEN_MAX);for (i = 0; i < max_fd;i++)close(i);//5,消除umask影响umask(0);//6,设置守护进程的工作目录chdir("/");//7,将标准输入,标准输出,标准错误重定向到/dev/nullopen("/dev/null",O_RDWR);dup(0);dup(0);}

二、日志系统

        

1,概念 

        linux系统提供了记录进程运行过程中的错误的信息的方法,即将错误信息记录在一个日志文件,这个日志文件就是系统日志,日志位置:/var/log/syslog

,如何记录进程的错误信息到系统日志文件 

    1》打开系统日志 

         #include <syslog.h>
         void openlog(const char *ident, int option, int facility);
         //参数1 ------- 字符串,表示进程信息的标记
         //参数2 ------- 选项: 
                            LOG_CONS       如果向日志中写信息时出错,将信息打印到控制台
                            LOG_NDELAY     立即发送信息
                            LOG_NOWAIT     不给子进程收尸,立即写信息到日志 
                            LOG_PERROR     在写日志的同时,向标准错误写数据
                            LOG_PID        在日志信息中添加进程的ID号
        //参数3 ------- 进程的类型 
                            LOG_DAEMON   ----守护进程 
                            LOG_FTP      ----ftp进程
                            LOG_KERN     ----内核进程 
                            LOG_LPR      ----打印系统
                            LOG_MAIL     ----邮件系统
       

      2》向日志文件中记录信息 

       void syslog(int priority, const char *format, ...);
       //参数1  ------ 消息的优先级: 
                            LOG_EMERG      系统级的错误
                            LOG_ALERT      应当立即纠正的错误
                            LOG_CRIT       紧急错误
                            LOG_ERR        一般错误
                            LOG_WARNING    警告
                            LOG_NOTICE     需要注意的问题
                            LOG_INFO       正常信息
                            LOG_DEBUG      调试信息

        //参数2 ----- 消息的格式控制串,类似于printf的第一个参数
        //变参  ------ 类似于printf中的变参。

        
        3》关闭系统日志    void closelog(void);

  
    例如:
 

 int main(int argc,char **argv){//让守护进程每隔一秒钟向文件中写一条时间信息FILE *fp;time_t tm;char buf[100];daemon_init();  //初始化守护进程//打开日志openlog("jjj",LOG_PID,LOG_DAEMON);if((fp = fopen("1.txt","r")) == NULL){//perror("fopen");syslog(LOG_ERR,"fopen:%s\n",strerror(errno));   //将进程中的错误信息记录到日志中exit(1);}while(1){time(&tm);sprintf(buf,"%s",ctime(&tm));fputs(buf,fp);fflush(fp);sleep(1);}closelog();  //关闭系统日志return 0;}

    //查看日志中的进程信息

    farsight@ubuntu:~/22071/process/day02_code$ grep jjj /var/log/syslog -rn
    832:Aug 18 20:44:27 ubuntu jjj[7255]: fopen:No such file or directory

三、文件锁

1,概念 

    文件锁:利用给文件上锁来解决进程之间的互斥问题。

2,给整个文件上锁 

     #include <sys/file.h>
             int flock(int fd, int operation);
     //参数1 ----- 文件描述符
     //参数2 ----- 锁的类型: 
                        LOCK_SH   -----共享锁
                        LOCK_EX   -----互斥锁
                        LOCK_UN   -----解锁
    //返回值 ---- 成功:0,失败:-1 

    例如: 

        flock01.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/file.h>int main(int argc,char **argv)
{int fd;int i;//打开某个用于上锁的文件if((fd = open("1.txt",O_RDWR|O_CREAT,0666)) < 0){perror("open");exit(1);}//先给文件上锁,才能上厕所if(flock(fd,LOCK_EX) < 0){perror("flock");exit(1);}//要上一号坑for(i = 0; i < 10; i++){printf("我是鹿晗,我正在一号坑位上厕所...\n");sleep(1);}//解锁if(flock(fd,LOCK_UN) < 0){perror("flock");exit(1);}printf("上完厕所真舒服!\n");return 0;
}

        flock02.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/file.h>int main(int argc,char **argv)
{int fd;int i;//打开某个用于上锁的文件if((fd = open("1.txt",O_RDWR|O_CREAT,0666)) < 0){perror("open");exit(1);}//先给文件上锁,才能上厕所if(flock(fd,LOCK_EX) < 0){perror("flock");exit(1);}//要上一号坑for(i =0 ; i < 10; i++){printf("我是蔡徐坤,我正在一号坑位上厕所...\n");sleep(1);}//解锁if(flock(fd,LOCK_UN) < 0){perror("flock");exit(1);}printf("上完厕所真舒服!\n");return 0;
}

3,给文件的某个区域上锁

    
    #include <unistd.h>
    #include <fcntl.h>

    int fcntl(int fd, int cmd, ... /* arg */ );
    //参数1 ------ 文件描述符
    //参数2 ------ 功能: 
                      复制文件描述符:                 F_DUPFD
                      设置或获取文件描述符flags       F_GETFD   F_SETFD 
                      设置或获取文件状态flags      F_GETFL  F_SETFL
                      设置或获取文件锁:    F_SETLK, F_SETLKW, and F_GETLK
                          struct flock {
                               short l_type;    /* Type of lock: F_RDLCK, F_WRLCK, F_UNLCK */
                               short l_whence;  /* How to interpret l_start: SEEK_SET, SEEK_CUR, SEEK_END  文件锁偏移的起始位置*/
                               off_t l_start;   /* Starting offset for lock 相对l_whence偏移的字节数,也就是锁的起始位置*/
                               off_t l_len;     /* Number of bytes to lock  锁的区域大小*/
                               pid_t l_pid;     /* PID of process blocking our lock (set by F_GETLK and F_OFD_GETLK)  上锁的进程的ID*/
                               ...
                           };
    //变参 -----根据参数2,变参的类型会有所不同    

    例如: //先上锁struct flock fl = {.l_type=F_WRLCK,.l_whence=SEEK_SET,   //文件锁偏移的起点.l_start=1024,        //相对上面成员的偏移量,也就是锁的起始位置.l_len=2048,          //锁的区域大小};if(fcntl(fd,F_SETLKW,&fl) < 0){perror("fcntl");exit(1);}//访问互斥资源的代码段..................//解锁fl.l_type = F_UNLCK;if(fcntl(fd,F_SETLK,&fl) < 0){perror("fcntl");exit(1);}

进程与线程基础day02--------守护进程、系统日志、文件锁相关推荐

  1. 进程和线程基础知识(已经是最详细的啦)

    进程和线程基础知识 文章目录 进程和线程基础知识 一.前言 二.进程 1.引入 2.并发和并行有什么区别? 3.进程与程序的关系的类比 4.进程的状态 5.进程的控制结构 6.进程的控制 7.进程的上 ...

  2. Linux进程管理:进程和线程基础知识

    <Linux进程管理:进程和线程基础知识> <Linux-进程管理> <C语言进程的内存地址空间分配> <进程和线程模型> <(1)Linux进程 ...

  3. c++时间片轮转rr进程调度算法_进程,线程基础(—)

    进程 进程简单的定义是指装载到内存的指令集并且正在由cpu执行其中的每一条指令的这个程序叫做进程. 进程控制块 process control block 简称PCB,主要包含了标识符,状态,优先级, ...

  4. 快速get进程、线程基础知识

    前言 为了方便大家理解进线程的工作流程及运行状态,先来看一篇小故事: 我们写好的一行行代码,为了让其工作起来,我们还得把它送进城(进程)里,那既然进了城里,那肯定不能胡作非为了. 但是城里有城里的规矩 ...

  5. ​五分钟扫盲:进程与线程基础必知

    全文脉络思维导图如下: 1. 进程与线程的简单解释 进程(Process)和线程(Thread)是操作系统的基本概念,但是它们比较抽象,不容易掌握.以下这个解释出自阮一峰老师的博客(http://ww ...

  6. 进程和线程基础知识全家桶,30 张图一套带走

    前言 先来看看一则小故事 我们写好的一行行代码,为了让其工作起来,我们还得把它送进城(进程)里,那既然进了城里,那肯定不能胡作非为了. 城里人有城里人的规矩,城中有个专门管辖你们的城管(操作系统),人 ...

  7. linux系统编程之进程(八):守护进程详解及创建,daemon()使用

    linux系统编程之进程(八):守护进程详解及创建,daemon()使用 一,守护进程概述 Linux Daemon(守护进程)是运行在后台的一种特殊进程.它独立于控制终端并且周期性地执行某种任务或等 ...

  8. Linux:守护进程解析、如何实现守护进程

    1.守护进程: 守护进程也称精灵进程(Daemon),是运行在后台的⼀一种特殊进程.它独立于控制终端且周期性地执行某种任务或等待处理某些发生的事件.守护进程是⼀一种很有用的进程.Linux的大多数服务 ...

  9. linux下查看进程的线程数,linux查看进程的线程数

    top -H -p $PID  #查看对应进程的那个线程占用CPU过高 1.top -H 手册中说:-H : Threads toggle 加上这个选项启动top,top一行显示一个线程.否则,它一行 ...

最新文章

  1. xp系统电脑ntp服务器,xp 设置ntp服务器
  2. 作为怀孕的亲历者,你觉得最值得分享的经验或者技巧是什么?
  3. CTreeCtrl控件的使用小记
  4. ecmall类关系图(转)
  5. Django学习笔记第三篇--关于响应返回
  6. 新的一年,如何高效学习前端前沿知识~
  7. mac地址和ip地址的区别(转)
  8. 最邻近插值、双线性插值、三次卷积插值最通俗入门理论解析,论文材料
  9. k上升段,对于排列问题的处理
  10. css遮罩层从下往上_CSS:图片自带3px下边距的bug修复
  11. 解决想从证书导出p12文件但是该证书中没有密码无法导出P12文件的问题
  12. 车,让你高效的高效工作,快乐生活
  13. 热强化硅酸钠玻璃建筑玻璃英国UKCA认证—EN 1863-2
  14. php充值代码,基于php的加油卡充值接口调用代码实例
  15. WCF学习之:利用Throttling提高服务器性能
  16. 【2022年高教杯数学建模】C题:古代玻璃制品的成分分析与鉴别方案及代码实现(一)
  17. matlab:实现“必应”的图片搜索功能并将图片保存
  18. 用mirai做机器人方法
  19. 快抖“变长”、爱优腾“变短”
  20. vue 实现前端excel导出表格携带token的两种方法

热门文章

  1. oracle中带有in查询的子查询绑定变量方式
  2. 软件java安卓版_AIDE软件下载-AIDE【Java开发IDE软件】下载v3.2.18 安卓版-西西软件下载...
  3. android内容提供者实验报告,实验报告审核的19个要点
  4. 微信体现计算机网络功能,教你微信提现如何免手续费
  5. 免费下载excel办公软件_Smartbi电子表格下载
  6. 电子科技大学和东北大学计算机专业哪个好,电子科技大学、南京航空航天大学、东北大学,你会怎么选择?...
  7. Java JDK安装与配置
  8. 博客中国2004中文非主流网站100强
  9. 函数prev_permutation和next_permutation的用法分辨
  10. windows8从安装到优化详细全过程——超详细图文教程