编写日志文件

news2024/11/16 23:39:13

在这里插入图片描述

精灵程序

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <signal.h>
#include <sys/shm.h>
#include <sys/resource.h>
#include <sys/file.h>


#define SPACE 0
#define DATA 1
#define MEM_PATH "/mnt/share/project/project_01/"

union semun
{
    int val;
    struct semid_ds *buf;
    unsigned short *array;
    struct seminfo *__buf;
};


void shm_init(int id,int num,int val);
void P(int id,int num);
void V(int id,int num);
void my_log(char *str);
void sumu(void);

int main()
{
	pid_t a;
	
	int max_fd,i;
	
	
	/***************************************************
	1.忽略SIGHUP信号(关闭终端),防止进程被CTTY控制终端关闭
	*****************************************************/
	
	signal(SIGHUP,SIG_IGN);
	
	/***************************************************
	2.生成第一个子进程,确保能够正确产生新的会话期
	*****************************************************/	
	
	a = fork();
	if(a > 0)
	{
		exit(0);
	}
	
	/***************************************************
	3.调用setsid()函数,让第一个子进程产生新的没有控制终端的会话期
	*****************************************************/	
	
	setsid();
	
	/***************************************************
	4.生成第二个子进程,防止精灵进程打开终端文件创建控制终端
	*****************************************************/	
	
	a = fork();
	if(a > 0)
	{
		exit(0);
	}
	
	/***************************************************
	5.分离精灵进程的原生进程组,防止接收到任何控制进程组的信号
	*****************************************************/	
	
	setpgrp();
	
	/***************************************************
	6.关闭所有的文件描述符,释放资源
	*****************************************************/	
	
	max_fd = sysconf(_SC_OPEN_MAX);
	for(i = 0; i < max_fd; i++)
	{
		close(i);
	}
	
	/***************************************************
	7.文件权限掩码清零
	*****************************************************/
	
	umask(0);
	
	/***************************************************
	8.改变进程的工作路径,确保进程不会被卸载
	*****************************************************/
	
	chdir("/");
	
	/***************************************************
	9.精灵进程创建成功
	*****************************************************/
	//精灵进程要干的事
	my_log("精灵进程启动\n");
	sumu();

	pause();
	return 0;
}

void sumu(void)
{
    //signal(SIGINT,SIG_IGN);//捕捉ctrl+c信号
    key_t key =ftok(MEM_PATH,1);
    //create shm
    int shmid=shmget(key,1024,IPC_CREAT|0666);
    if(-1==shmid)
    {
        perror("shmget erro");
        exit(1);
    }
    //create 2 sem
    int semid=semget(key,2,IPC_CREAT|0666);
    if(-1==semid)
    {
        perror("semget erro");
        exit(1);
    }
    
    //init sem
    shm_init(semid,SPACE,1);//space设置信号量0为1
    shm_init(semid,DATA,0);//data设置信号量1为0

    char *p=shmat(shmid,NULL,0);
    if(NULL==p)
    {
        perror("shmat erro");
        exit(1);
    }

    printf("recv start\n");
    while(1)
    {
        P(semid,DATA);
        printf("recv:%s",p);
        my_log(p);
        V(semid,SPACE);
        if(!strncmp(p,"quit",4))
        {
            break;
        }
        
    }
    shmdt(p);
    return ;
}

void shm_init(int id,int num,int val)
{
    union semun a;
    a.val=val;
    semctl(id,num,SETVAL,a);
}

void P(int id,int num)
{
    struct sembuf sops[1];
    sops[0].sem_num=num;//信号量元素编号
    sops[0].sem_op=-1;//P操作
    sops[0].sem_flg=0;//0表示阻塞
    semop(id,sops,1);//执行P操作
}
void V(int id,int num)
{
    struct sembuf sops[1];
    sops[0].sem_num=num;//信号量元素编号
    sops[0].sem_op=1;//V操作
    sops[0].sem_flg=0;//0表示阻塞
    semop(id,sops,1);//执行V操作
}

void my_log(char *str)
{
    int fd = open("/mnt/share/project/project_01/log.txt",O_CREAT|O_RDWR|O_APPEND);
    if(-1 == fd)
    {
        perror("open erro");
        return;
    }
    write(fd,str,strlen(str));
    close(fd);
}

app函数(用户函数)

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <signal.h>
#include <sys/shm.h>
#include <time.h>

#define SPACE 0
#define DATA 1
#define MEM_PATH "/mnt/share/project/project_01/"

void shm_init(int id,int num,int val);
void P(int id,int num);
void V(int id,int num);

union semun
{
    int val;
    struct semid_ds *buf;
    unsigned short *array;
    struct seminfo *__buf;
};

struct sembuf sops;

int main(int argc,char const *argv[])
{
    signal(SIGINT,SIG_DFL);//捕捉ctrl+c信号,恢复默认信号处理函数
    key_t key =ftok(MEM_PATH,1);
    //create shm
    int shmid=shmget(key,1024,IPC_CREAT|0666);
    if(-1==shmid)
    {
        perror("shmget erro");
        exit(1);
    }
    //create 2 sem
    int semid=semget(key,2,IPC_CREAT|0666);
    if(-1==semid)
    {
        perror("semget erro");
        exit(1);
    }
    
    //init sem
    shm_init(semid,SPACE,1);//space设置信号量0为1
    shm_init(semid,DATA,0);//data设置信号量1为0

    char *p=shmat(shmid,NULL,0);//将shm映射到进程空间
    if(NULL==p)
    {
        perror("shmat erro");
        exit(1);
    }
    //获取日志的信息
    int pid = getpid();
    time_t now;
    time(&now);

    while (1)
    {
        memset(p,0,1024);
        P(semid,SPACE);//空间-1
        // printf("please input:");
        // fgets(p,1024,stdin);
        sprintf(p,"pid=%d,time=%s",pid,ctime(&now));
        V(semid,DATA);//数据+1
        
        if(!strncmp(p,"quit",4))
        {
            break;
        }
        //添加延迟
        usleep(1000000);
        
    }
    shmdt(p);
    return 0;
}

void shm_init(int id,int num,int val)
{
    union semun a;
    a.val=val;
    semctl(id,num,SETVAL,a);
}

void P(int id,int num)
{
    struct sembuf sops[1];
    sops[0].sem_num=num;//信号量元素编号
    sops[0].sem_op=-1;//P操作
    sops[0].sem_flg=0;//0表示阻塞
    semop(id,sops,1);//执行P操作
}
void V(int id,int num)
{
    struct sembuf sops[1];
    sops[0].sem_num=num;//信号量元素编号
    sops[0].sem_op=1;//V操作
    sops[0].sem_flg=0;//0表示阻塞
    semop(id,sops,1);//执行V操作
}

日志文件

在这里插入图片描述

结果图

在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2052915.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue3 响应式 API:ref() 和 reactive()

在 Vue 3 中&#xff0c;响应式系统是其核心特性之一&#xff0c;它使得数据的变化能够自动触发视图的更新。 官方文档&#xff1a; 响应式 API&#xff1a;核心 要更好地了解响应式 API&#xff0c;推荐阅读官方指南中的章节&#xff1a; 响应式基础 (with the API preference…

【STM32单片机_(HAL库)】3-2-1【中断EXTI】【电动车报警器项目】震动点灯

1.硬件 STM32单片机最小系统LED灯模块震动传感器模块 2.软件 exti驱动文件添加GPIO常用函数中断配置流程main.c程序 #include "sys.h" #include "delay.h" #include "led.h" #include "exti.h"int main(void) {HAL_Init(); …

Linux常用命令 ---- rmdir 命令[删除一个空目录]

rmdir 命令 功能&#xff1a;删除一个空目录 我们使用 mkdir 命令创建一个名为 test 空文件夹&#xff0c;如下图所示。 现在使用 rmdir 命令将 test 文件夹进行删除&#xff0c;如下图所示。 注意&#xff1a;rmdir 命令只能删除一个空目录&#xff0c;如果这个目录中有其他文…

【云原生】Kubernetes中的名称空间和资源配额详细用法与应用实战

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全…

医疗器械维修其实没有想的那么难

在很多人的印象中&#xff0c;医疗器械维修是一项极其复杂且神秘的工作&#xff0c;似乎只有专业的技术精英才能胜任。然而&#xff0c;事实并非如此&#xff0c;医疗器械维修其实并没有想象中那么难。 首先&#xff0c;现代医疗器械的设计越来越注重人性化和可维护性。制造商…

迎接开学新生活!高三开学必备物品推荐~

步入高三&#xff0c;意味着每一位学子都将面临人生中重要的转折点——高考。为了帮助高三学生们准备充分&#xff0c;让学习生活之路更加顺畅。今天小编综合了实用性、性价比以及学生需求的考量&#xff0c;精选了一系列必备物品&#xff0c;旨在为高三学生创造一个更为舒适、…

ICMP互联网控制报文协议

ICMP 互联网控制报文协议 ICMP &#xff08; Internet Control Message Protocol &#xff0c;也就是互联⽹控制报⽂协议&#xff09;。 ⽹络包在复杂的⽹络传输环境⾥&#xff0c;常常会遇到各种问题。 当遇到问题的时候&#xff0c;总不能死个不明不⽩&#xff0c;没头没脑…

4. kafka消息监控客户端工具

KafkaKing官网地址 : https://github.com/Bronya0/Kafka-King github下载地址 : Releases Bronya0/Kafka-King (github.com) (windows、macos、linux版本) 云盘下载地址 : https://pan.baidu.com/s/1dzxTPYBcNjCTSsLuHc1TZw?pwd276i (仅windows版本) 连接kafka 输入本地地址…

基于Java语言的私家车充电桩系统+私家车充电平台+充电桩系统项目

介绍 SpringBoot 框架&#xff0c;私家车充电桩平台充电桩系统充电平台充电桩云快充协议1.5-1.6协议新能源汽车二充电平台源码Java源码私家车充电系统 源码合作 提供无加密源代码和数据库&#xff0c;支持二次开发 SpringMVC架构完整充电桩系统源代码-充电桩系统-家充公充-新…

大数据报表如何免费设计?本攻略附赠强大报表工具!

在当今信息爆炸的时代&#xff0c;大数据跃升为企业战略决策的核心支撑点。如何有效地从浩瀚的数据海洋中精炼出富含洞察力的信息&#xff0c;并将其转化为直观易懂的报表&#xff0c;是每个数据分析师和决策者都需要面对的挑战。这需要掌握一定的技巧和经验&#xff0c;本文将…

C语言03--控制流

1.二路分支 逻辑&#xff1a;程序中某段代码需要在满足某个条件时才能运行形式&#xff1a; if 语句&#xff1a;表达一种 如果-则 的条件执行关系if-else 语句&#xff1a;表达一种 如果-否则 的互斥分支关系 语法&#xff1a; if ( 判断表达式 ) { // 代码块 } 解…

大学生最佳就业城市排行榜出炉!

最佳就业城市 随着秋招陆续开始&#xff0c;不少高校毕业生迎来了人生转折点。 其中一个需要重点考虑的点&#xff0c;是要前往哪座城市作为就业第一站。 不妨参考一下就业蓝皮书的统计数据&#xff1a; 可以发现&#xff0c;一线城市的就业人数正逐步减少&#xff0c;"新…

grid-template-columns: 1.833333rem 1fr;

问: grid-template-columns: 1.833333rem 1fr;这是什么属性? 回答: grid-template-columns: 1.833333rem 1fr; 定义了一个网格布局的列宽&#xff1a; 1.833333rem 表示第一列的宽度是相对于根元素字体大小的固定宽度, 1fr 是一个灵活单位&#xff0c;表示第二列会占据网…

【吊打面试官系列-Memcached面试题】memcached 最大的优势是什么?

大家好&#xff0c;我是锋哥。今天分享关于 【memcached 最大的优势是什么&#xff1f;】面试题&#xff0c;希望对大家有帮助&#xff1b; memcached 最大的优势是什么&#xff1f; Memcached 最大的好处就是它带来了极佳的水平可扩展性&#xff0c;特别是在一个巨大的系统中。…

[Python办公]Pandas创建透视表入门2

pivot_table 透视表在 Pandas 中是一个非常强大和灵活的工具&#xff0c;它支持许多高级功能&#xff0c;可以用于复杂的数据分析和报告生成。以下是一些更高级的用法和详细说明 1. 多级索引&#xff08;MultiIndex&#xff09; pivot_table 支持多级索引&#xff0c;这意味着…

iPhone16操作按钮大变样?引入快门拍摄按钮,提前告诉你它要干啥

随着智能手机摄影功能的不断升级&#xff0c;用户对于高质量照片和视频的需求也日益增长。苹果公司一直以来都在引领移动摄影技术的发展方向&#xff0c;而即将到来的iPhone 16系列更是备受瞩目。据多个消息来源透露&#xff0c;iPhone 16将引入一项创新功能——一个专门设计用…

【python实现修改所有可执行程序的图标】

实现效果&#xff1a; 图标在此 替换前&#xff1a; 吐槽&#xff1a;这原版看着也不像原版&#x1f603; 替换后&#xff1a; 代码&#xff1a; 注&#xff1a;必须要.ico图标文件 import winreg import ctypes import sys import os# 使用管理员身份打开程序 ctypes.windll…

3万多育儿宝典育儿网站ACCESS\EXCEL数据库

找了下以前弄到的一些育儿数据&#xff0c;发现小数据的《育儿宝典育儿知识大全ACCESS数据库》《结构漂亮的怀孕手册ACCESS数据库》、《结构漂亮的亲子宝典ACCESS数据库》&#xff0c;大的数据有《3万妈妈说育儿百科知识ACCESS数据库》而今天又弄到了一个3万多的育儿宝典网站&a…

ArcGIS Pro基础:状态栏显示栏的比例尺设置和经纬度位置

上图所示&#xff0c;界面下方最左侧是显示的比例尺&#xff0c;可以进行选择设置&#xff0c;也可以进行自定义设置 上图所示&#xff0c;可以手动录入比例尺&#xff0c;同时也可以对比例尺设置别名&#xff0c;比如【实验1】作为特定比例尺的标记 如上图所示&#xff0c;可以…

火语言RPA流程组件介绍--变量持久化及读取

变量持久化及读取 对于一些常用变量在下次或其他流程需要继续使用时&#xff0c;可以将内存中的变量持久化保存到该组件格式化的特定本地文件中&#xff0c;在下次或其他流程使用时从文件读取数据输出至下一个组件或变量&#xff0c;常用来保存难以初始化或者在流程中进行特定…