【linux】linux随记4-系统编程

文章详细阐述了Linux中exit和_exit函数在进程退出时的不同,前者会清空IO缓冲区,后者则不会。wait函数用于父进程等待子进程结束,并获取其退出状态。同时,介绍了进程的不同状态,包括运行、睡眠、暂停、僵尸和死亡等。此外,还讲解了如何创建守护进程以及处理僵尸进程的方法。
摘要由CSDN通过智能技术生成

一、exit(status)和_exit(status)

  • exit(status) : 退出进程是会查看当前进程的IO缓冲区,把IO缓冲区的内容打印出到标椎输出(屏幕)
  • _exit(status) : 直接退出进程,不会打印出IO缓冲区的内容
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>

//exit(0);會區找當前進程的IO緩衝區,把裏面的內容取出打印出來
//_exit(0);不會打印出IO緩衝區的內容,直接退出進程
//printf的數據會先存入IO緩衝區,遇到\n才會從IO緩衝區取出數據打印到屏幕上
int main() 
{
	pid_t result;
	result=fork();
	if(result == -1)
		printf("fork error!\r\n");
	if(result == 0)
	{
		printf("son");
		_exit(0);
	}
	
	else
	{
		printf("parent");
		exit(0);
	}
	
	return 0;
}

结果:终端打印出parent 没有打印出son
在这里插入图片描述

二、void wait(int *status)

  • wait(&status) : 写在父进程中等待子进程执行结束,但是这样写很粗暴,会阻塞父进程,一般是子进程退出时,发送一个信号通知给父线程,父线程接收到信号后,再使用WIFEXITED(status) 和 WEXITSTATUS(status) 获取子进程的退出值
  • WIFEXITED(status) :如果子进程正常退出,该值为真
  • WEXITSTATUS(status):如果子进程退出正常,该宏能获取子进程的退出值
#include<stdio.h>
#include<sys/wait.h>
#include <unistd.h>
#include<stdlib.h>

int main()
{
	pid_t result;
	int status;
	result = fork();
	if(result == -1)
		printf("error!\r\n");
	if(result == 0)
	{
		printf("son\r\n");
		exit(11);//退出值为11
	}
	else
	{
		printf("parent\r\n");
		wait(&status);
		if(WIFEXITED(status) == 1) 
			printf("exit value:%d\r\n",WEXITSTATUS(status));

在这里插入图片描述

三、进程的生老病死

在这里插入图片描述

进程状态(宏):

  • TASK RUNNING:就绪运行状态 (运行)
  • TASK_INTERRUPTIBLE:可中断睡眠状态 (睡眠)
  • TASK_UNINTERRUPTIBLE:不可中断睡眠状态 (睡眠)
  • TASK TRACED:调试态 (暂停)
  • TASK_STOPPED:暂停状态 (暂停)
  • EXIT_ZOMBIE:僵死状态 (僵尸)
  • EXIT_DEAD;死亡态 (死亡)

前后台进程组

  • 执行程序时加上 & 可让程序运行在后台,不占用终端 // 如./a.out &
  • jobs 命令可查看后台进程组起他们的jobsID
  • ctrl+z 可使前台进程转换为后台进程,并停止
  • fg+jobsID 可使后台进程转换为前台进程

守护进程

  • fork创建子进程,父进程直接退出// fork()
  • 创建一个新的会话,摆脱终端的影响// setsid()
  • 改变守护进程的当前工作目录,该为“/” //chdir();
  • 重设文件权限掩码 //umask命令可查看文件权限掩码 umask(int)改变文件权限掩码
    //文件默认权限 0666(8进制),umask:022 真正文件权限 066 &~ umask
  • 关闭不需要的文件描述符 0 1 2 即标椎输入 输出 错误 //close()
#include<stdio.h>
#include<sys/wait.h>
#include <unistd.h>
#include<stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include<fcntl.h>
#include <string.h>
int main()
{
    pid_t pid;
    int fd, len;
    const char* buf = "the daemon is running\r\n";
    len = strlen(buf);
    if((pid = fork()) < 0)
    {
        printf("fork error\r\n");
        exit(1);
    }
    else if(pid == 0)
    {
       
        setsid();
        chdir("/");
        umask(0);
        for(int i=0;i<3;i++)
        {
            close(i);
        }
      
        while(1)
        {
            fd = open("/home/wzt/Code/system_programming/part_5/daemon1.log",O_CREAT|O_WRONLY|O_APPEND,0666);
            if(fd < 0)
            {
                printf("open error\r\n");
            }
            write(fd, buf, len);
            close(fd);
            sleep(5);
        }
    }
    else
    {
       exit(0); 
    }
    return 0;
}

普通进程伪装成守护进程: nohup命令 // nohup sleep 100 &

僵尸进程

正常程序退出:

  • 子进程用exit()函数退出
  • 父进程调用wait()函数等待
    僵尸进程:子进程退出后,父进程没有调用wait()函数处理身后事,子进程变成僵尸进程

托孤进程

  • 父进程先于子进程退出,子进程变成孤儿进程,linux系统会孤儿进程托孤给init进程
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值