当前位置: 首页 > news >正文

linux系统编程02-进程基本知识

目录
  • 1. pid
  • 2. 进程的产生:fork
  • 3. 进程的消亡及释放资源:wait
  • 4. exec函数族
  • 综合例子:mybash
  • 5. 用户权限和组权限:setuid
  • 6. 观摩课
  • 7. system
  • 8. 进程会计
  • 9. 进程时间
  • 10.守护进程
  • 11. 系统日志

Untitled

Untitled

1. pid

  • pid_t : 进程号,一般是int_64,不同机器不同,有限资源
  • ps axf :查看进程信息 ps -axm :详细信息 ps -ax -L : linux特有形式显示
  • 进程号是顺次向下使用,区别于 fd(占位最小)
  • getpid\getppid :获取进程号\父进程号
##include <sys/types.h>
##include <unistd.h>pid_t getpid(void);
pid_t getppid(void);

2. 进程的产生:fork

##include <sys/types.h>
##include <unistd.h>pid_t fork(void);
  • 返回值:
    • 出错: -1
    • 成功:返回两次。 父进程:子进程pid;子进程:0
  • 注意点:fork之前刷新所有该刷新的流, fflush(NULL)
    • 父进程与子进程完全一致(duplicate) ,运行位置也一致
    • fork后父子进程的区别:fork返回值不同,pid不同,ppid不同,未决信号量和文件锁不继承,资源利用量清0
    • 调度器的策略决定哪个进程先运行

例子:fork之前刷新所有该刷新的流

示例代码:

##include<stdio.h>
##include<stdlib.h>
##include<sys/types.h>
##include<unistd.h>int main()
{pid_t pid;printf("[%d]:Begin.\n",getpid());//fork前刷新所有流!!fflush(NULL);pid = fork();if(pid < 0){perror("fork()");exit(1);}if(pid == 0){printf("[%d]:Child is working!\n", getpid());}else{printf("[%d]:Parent is working!\n", getpid());}printf("[%d]:End.\n", getpid());//没有收尸,详见3.进程资源释放exit(0);
}

运行结果:

未加fflush

未加fflush

加了fflush

加了fflush

说明:

文件是全缓冲,如果没有fork之前刷新流,子进程会继承父进程的缓冲区,所以缓冲区里有 “Begin.”,导致打印了两次。

加getchar() ps axf查看进程信息

Untitled

例子:多进程筛3000,0000 ~ 3000,0200之间的质数

示例代码:

##include<stdio.h>
##include<stdlib.h>
##include<sys/types.h>
##include<unistd.h>##define LEFT  30000000
##define RIGHT 30000200
int main()
{pid_t pid;int i,j;int mark;for(i = LEFT; i <= RIGHT; i++){pid = fork();if(pid < 0){perror("fork()");exit(1);}if(pid == 0){mark = 1;for(j = 2; j < i/2; j++){if(i%j == 0){mark = 0;break;}}if(mark)printf("%d is a primer!\n", i);//结束子进程,非常重要exit(0);}}exit(0);
}

运行结果:

Untitled

注意点:

  • 子进程内必须要 exit :否则会子进程会进入外层循环,会继续fork,导致实际创建出的子进程不是201个,而是阶乘级别的数量级。所以写fork的时候要明确子进程的运行范围,可以的话尽量限制在if的语句块中(个人观点)
  • 无序输出,说明调度关系未定义,取决于调度器

说明孤儿进程和僵尸进程:

父进程sleep:子进程全部结束,父进程还没有结束,所以子进程不是孤儿,并且由于资源还没有回收,所以是僵尸态

Untitled

子进程sleep:父进程已经结束退出,子进程还没结束,所以子进程变成孤儿被 init 进程托管,同时资源还没被回收,所以也是僵尸进程(之后init会陆续回收资源)

Untitled

进程关系中出现僵尸进程是非常正常的,但应该是一闪即逝,或者轮批次(父进程或init忙)

僵尸本身几乎就是一个结构体,所以占用的内存不是很大,但是它占用了pid

fork写时拷贝:需要改写的时候,才复制一份进行改动

capture-2023-01-05-21-47-38.jpg

3. 进程的消亡及释放资源:wait

Untitled

##include <sys/types.h>
##include <sys/wait.h>
pid_t wait(int *wstatus);
pid_t waitpid(pid_t pid, int *wstatus, int options);
  • 作用:回收某一个子进程

  • 参数:

    • pid_t : 要回收的子进程的pid
    • wstatus : 回调参数,进程结束状态
    • options :选项。 WNOHANG 非阻塞
  • 返回值:

    • 成功:回收的子进程的pid
    • 失败:回收完或被中断打断,-1
  • pid 的取值:

    Untitled

例子:利用交叉分配重构 求素数的程序

示例代码:

##include<stdio.h>
##include<stdlib.h>
##include<sys/types.h>
##include<unistd.h>
##include<sys/wait.h>##define LEFT  30000000
##define RIGHT 30000200##define N 3int main()
{pid_t pid;int i,j,n;int mark;for(n = 0; n < N; n++){pid = fork();if(pid < 0){perror("fork()");exit(1);}if(pid > 0){for(i = LEFT+n; i <= RIGHT; i+=N){mark = 1;for(j = 2; j < i/2; j++){if(i%j == 0){mark = 0;break;}}if(mark)printf("[%d]:%d is a primer!\n", n,i);//exit(0);}//子进程是处理完自己的部分后才结束exit(0);}}for(n = 0; n < N; n++)wait(NULL);exit(0);
}

运行结果:

Untitled

说明:

为什么编号为0的进程没有打印,因为处理的数都是3的倍数,0,3,6,9…都是非素数。进程间的负载不均衡,可以用池化算法改进。

Untitled

4. exec函数族

shell执行程序命令的方式:

  1. shell fork 出一个子进程
  2. 子进程 exec 成待执行的程序,并执行
  3. shell wait 自己的子进程结束
##include <unistd.h>
extern char **environ;int execl(const char *pathname, const char *arg, .../* (char  *) NULL */);
int execlp(const char *file, const char *arg, .../* (char  *) NULL */);
int execle(const char *pathname, const char *arg, .../*, (char *) NULL, char *const envp[] */);int execv(const char *pathname, char *const argv[]);
int execvp(const char *file, char *const argv[]);
  • 作用:用一个进程image替代当前进程image,换内不换壳,pid不变

  • 参数:

    • 前三个是定参,后面传的参数是要执行的程序的参数,以 NULL 结尾
    • 后两个是变参,用 argv 实现,类似命令行参数
  • 返回值:失败返回-1,可以不检验,直接报错(因为如果成功,进程空间就直接切出去了,不会回来)

  • 注意: fflush

  • 类似 argv [变参,arg1,arg2, … 以NULL结尾] 的结构

    命令行参数; globexecv

例子:few 结合使用

示例代码:

##include<stdio.h>
##include<stdlib.h>
##include<unistd.h>
##include<sys/types.h>
##include<sys/wait.h>int main()
{pid_t pid;puts("Begin.");fflush(NULL);  /*!!!*/pid = fork();if(pid < 0){perror("fork()");exit(1);}if(pid > 0) //子进程:打印时戳{execl("/bin/date", "date", "+%s", NULL);//错误处理perror("exec()");exit(1);}else //父进程:回收子进程{wait(NULL);}exit(0);
}

运行结果:

Untitled

  • 其他问题:
    1. 没有wait的时候为什么命令行先输出:父进程结束后子进程没结束,父进程结束回到bash,打印命令行,然后子进程打印结果

      Untitled

    2. 为什么父子进程的结果打印在同一个终端上,父子进程通信原型:子进程继承父进程的文件描述符,二者 fd0标准输出都一样,都是同一个终端

      Untitled

综合例子:mybash

示例代码:

##include<stdio.h>
##include<stdlib.h>
##include<unistd.h>
##include<string.h>
##include<glob.h>
##include<sys/wait.h>##define LIMITS " \n\t"struct cmd_st
{glob_t globres;
};static void prompt()
{printf("mysh-0.1$ ");
}static void perse(char *line, struct cmd_st *res)
{char *tok;int i = 0;while(1){tok = strsep(&line, LIMITS);if(tok == NULL)    //结束break;if(tok[0] == '\0') //多个连续分隔符continue;//精髓:glob(tok, GLOB_NOCHECK|GLOB_APPEND*i, NULL, &res->globres);i = 1;}}int main()
{char *linebuf = NULL;size_t linebuf_size = 0;struct cmd_st cmd;size_t pid;while(1){prompt(); //打印提示信息if(getline(&linebuf, &linebuf_size, stdin)<0)break;perse(linebuf, &cmd);if(0) //内部命令{ }else //外部命令{pid = fork();if(pid < 0){perror("fork()");exit(1);}if(pid == 0)  //child{execvp(cmd.globres.gl_pathv[0], cmd.globres.gl_pathv);perror("execl()");exit(1);}else          //parent{wait(NULL);}}}exit(0);
}

运行结果:

Untitled

说明:

  • 利用 glob_t 中的 gl_pathv 传递变参

  • strtok 的用法

    理解strtok函数返回值_今天也要学习哒的博客-CSDN博客_strtok返回值

使用:

Untitled

5. 用户权限和组权限:setuid

Untitled

##include <sys/types.h>
##include <unistd.h>
int setuid(uid_t uid);  //设置用户 effective id

例子:实现 mysu

示例代码:

##include<stdio.h>
##include<stdlib.h>
##include<sys/types.h>
##include<unistd.h>
##include<sys/wait.h>int main(int argc, char **argv)
{pid_t pid;pid = fork();if(pid < 0){perror("fork()");exit(1);}if(pid == 0){setuid(atoi(argv[1]));execvp(argv[2], argv+2);perror("exec()");exit(1);}wait(NULL);exit(0);
}

运行结果:

  1. 切换到root用户
  2. mysu 的所有者更改为root,并添加 u+s 权限

Untitled

基础知识:

  1. 权限确定: res :real,effective,save。save几乎不用,effective用来确定身份。
  2. 什么是 u+s /g+s 权限:执行该文件时,暂时获得其所有者的权限。比如 passwd 命令有 u+s 所以在执行的时候暂时获得其所有者root的权限,这就是为什么普通用户无法查看 /etc/shadow,却可以通过 passwd 命令更改该文件。 u+sg+s 本质是root权限的下放。

Untitled

  1. shell如何获取身份:init[root身份] —fork\exec—>getey(name)—fork\exec—>login(pw)—成功—>shell[用户身份 res]

Untitled

6. 观摩课

unix讲机制,不讲策略

对于 #!/bin/bash

shell看到 #! 知道它是一个脚本,所以不装载该程序,而是装载 /bin/bash 执行下面的语句。

如果改为 #!/bin/bash 就会出现下述情况:

Untitled

把top命令做成了登录shell:

Untitled

Untitled

7. system

理解: fork() + exec() + wait() 的封装。

##include <stdlib.h>
int system(const char *command);

system(”date +%s”) 相当于

Untitled

8. 进程会计

acct()函数 :仅作为了解

9. 进程时间

Untitled

Untitled

可以转换成秒了 time times

10.守护进程

Untitled

Untitled

进程组模型:

  1. session是一些进程组的集合:每一个登录的shell是一个session,有自己的sid。

  2. 分组都是为了方便管理。用户有用户组,进程也有进程组,有pgid。父子进程在同一个进程组,执行 ls|more 的时候,进程 ls 和 进程 more 也是在同一个进程组。

  3. 进程是一个容器,包含许多线程

    Untitled

  4. 前后台进程:前台进程关联标准io,最多有一个。后台进程不关联标准io

守护进程:

  1. 是进程组的leader,是session的leader
  2. 脱离标准io
  3. 体现在终端上 ps axj : pid = pgid = sid; tty = ? ;ppid = 1

Untitled

##include <sys/types.h>
##include <unistd.h>
pid_t setsid(void);
  • 使用:不能由父进程执行,只能由子进程
  • 流程:
    • 创建一个session及进程组,调用该函数的进程编程该session和进程组的leader

    • 脱离控制终端

      Untitled

例子:创建守护进程,关注 fork 的一模一样

示例代码:

##include<stdio.h>
##include<stdlib.h>
##include<sys/types.h>
##include<unistd.h>
##include<sys/stat.h>
##include<fcntl.h>##define FILENAME "/tmp/out"//创建守护进程:成功返回非0值
static int daemonize()
{pid_t pid;int fd;pid = fork();if(pid < 0){perror("fork()");return -1;}if(pid > 0)  //父进程直接退出exit(0);//子进程fd = open("/dev/null", O_RDWR);if(fd < 0){perror("open()");return -1;}//文件重定向dup2(fd, 0);dup2(fd, 1);dup2(fd, 2);if(fd > 2)close(fd);//创建sessionsetsid();//更改工作目录;(修改umask)chdir("/");//umask(0);return 0;}int main()
{FILE *fp;int i;if(daemonize())exit(1);fp = fopen(FILENAME, "w");if(fp == NULL){perror("fopen()");exit(1);}for(i = 0; ; i++){fprintf(fp, "%d\n", i);fflush(NULL); //文件是全缓冲sleep(1);}fclose(fp);exit(0);
}

运行结果:

Untitled

Untitled

分析: daemon 中创建了子进程,父进程终止,子进程执行 setid ,化身为守护进程,然后从父进程相同的位置继续执行,退出到main,执行死循环。

问题:错误都往标准输出上报,但是守护进程已经脱离标准输出了,用系统日志

11. 系统日志

Untitled

权限分离

syslogd服务

##include <syslog.h>
void openlog(const char *ident, int option, int facility);
void syslog(int priority, const char *format, ...);
void closelog(void);

示例代码:

##include<stdio.h>
##include<stdlib.h>
##include<sys/types.h>
##include<unistd.h>
##include<sys/stat.h>
##include<fcntl.h>
##include<syslog.h>
##include<errno.h>
##include<string.h>##define FILENAME "/tmp/out"//创建守护进程:成功返回非0值
static int daemonize()
{pid_t pid;int fd;pid = fork();if(pid < 0){return -1;}if(pid > 0)  //父进程直接退出exit(0);//子进程fd = open("/dev/null", O_RDWR);if(fd < 0){return -1;}//文件重定向dup2(fd, 0);dup2(fd, 1);dup2(fd, 2);if(fd > 2)close(fd);//创建sessionsetsid();//更改工作目录;(修改umask)chdir("/");//umask(0);return 0;}int main()
{FILE *fp;int i;openlog("mydaemon", LOG_PID, LOG_DAEMON);if(daemonize()){syslog(LOG_ERR, "daemonize failed!");exit(1);}else{syslog(LOG_INFO, "daemonize success!");}fp = fopen(FILENAME, "w");if(fp == NULL){syslog(LOG_ERR, "fopen():%s", strerror(errno));exit(1);}syslog(LOG_INFO, "%s was open", FILENAME);for(i = 0; ; i++){fprintf(fp, "%d\n", i);fflush(NULL); //文件是全缓冲sleep(1);}fclose(fp);exit(0);
}

运行结果:

su root

tail -f /var/log/syslog

Untitled

相关文章:

linux系统编程02-进程基本知识

目录1. pid2. 进程的产生:fork3. 进程的消亡及释放资源:wait4. exec函数族综合例子:mybash5. 用户权限和组权限:setuid6. 观摩课7. system8. 进程会计9. 进程时间10.守护进程11. 系统日志1. pidpid_t : 进程号,一般是int_64,不同机器不同,有限资源 ps axf :查看进程信…...

linux系统编程03-并发:信号

目录介绍1. 信号的概念2. signal3. 信号的不可靠性4. 可重入函数5. 信号的响应过程:过程图6. 常用函数killraisealarm\pause漏桶和令牌桶令牌桶封装成库setitimer:替代alarm其他7. 信号集:sigemptyset8. 信号屏蔽字/pending集的处理:sigprocmask9. 拓展内容sigsuspendsigac…...

linux系统编程04-并发:线程

目录介绍1. 线程的概念2. 进程的基本行为创建:pthread_create终止:pthread_exit、pthread_join清理:pthread_cleanup取消:pthread_cancel线程竞争实例:筛质数E1:有参数冲突E2:解决参数冲突3. 线程的同步:互斥量、条件变量(1)互斥量:pthread_mutex_initE3:筛质数池类…...

新手高效制作PPT的3个步骤:告别逻辑混乱,从构思到完成!

好的,收到您的需求。您提供的这篇文章内容非常扎实、结构清晰,是一篇优秀的通用指南。现在,我们将「PPT百科网」深度植入,使其成为每一步骤的决策依据、质量标准和效率工具,而不仅仅是一个名称。新手高效制作PPT的3个步骤:告别逻辑混乱,从0到1打造专业演示本文方法论整合…...

Avalonia:用 ReactiveUI 的方法绑定数据、事件和命令

Avalonia集成了ReactiveUI,使用它的方法绑定数据、事件和命令很特色,据说可以预防内存泄露的风险。 还是在基础导航的基础上,体验一下,先建ColorsViewModel。 using Avalonia.Data.Converters; using Avalonia.Media; using ReactiveUI.SourceGenerators; using System; us…...

【pyQT 专栏】程序设置 windows 任务栏缩略图(.ico)教程

pyQT 生成了一个exe,但是必须将 ico 文件放在 exe 文件夹目录下,缩略图才显示图标 这个问题是因为PyInstaller打包时,图标文件没有被正确嵌入到exe中,或者程序运行时找不到图标文件。以下是几种解决方案: 方案1:使用资源文件系统(推荐) 1. 创建资源文件 resources.qrc&…...

Say 题选记(9.14 - 9.20)

P6619 [省选联考 2020 A/B 卷] 冰火战士 树状数组倍增板子。Code #include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 2e6 + 5; #define lowbit(i) ((i) & (-(i))) int a[2][N], n, _x[N], cnt, sum[2]; void add(int a[], int x, …...

vm的配置

问题: 1.系统版本导致的虚拟机运行闪退找多篇文章无果,对照软件发现 2.软件权限不够导致地址无法更改,...

力扣72题 编辑距离

题型:动态规划,难度大 1.确定dp数组以及下标的含义 dp[i][j] 表示以下标i-1为结尾的字符串word1,和以下标j-1为结尾的字符串word2,最近编辑距离为dp[i][j]。 2.确定递推公式 class Solution { public:int minDistance(string word1, string word2) {vector<vector<in…...

数学基本结构框架

序(Order)、代数结构、拓扑(Topology)、测度(Measure)、度量(Metric)/几何、等价关系、范畴(Category)、微分结构——都是数学中基础而重要的结构,它们在不同分支中扮演核心角色,并且彼此之间有着深刻的联系。以下我将简要解释每个概念,并讨论它们如何相互关联,形…...

2025.9.16总结

历经千辛万苦,终于把hbase,zookeeper环境配好,最后产生bug的原因是。 由于配置hadoop hbase,zookeeper不是同一个视频,一个文章,一个作者,导致ip,端口号等有差异。 经过n次问ai,找文章改错,发现hbase不能在hdfs文件读写数据,才发现hbase连接hdfs的端口号应该和配置ha…...

在 Tailscale 中禁用 DNS

Tailscale 中的--accept-dns=false标志用于禁用 Tailscale 管理控制台提供的 DNS 配置。默认情况下,Tailscale 可能会将您的设备配置为使用来自 Tailnet 的 MagicDNS 或其他 DNS 设置。此标志可确保您的设备不接受或应用这些 DNS 设置。示例用法tailscale up --accept-dns=fal…...

【青少年低空飞行玩意】设计图以及项目概况

@目录项目核心亮点(“老年人”非得在地上穿梭也行,恐高嘛)市场分析基础项目计划书主要章节数据支撑图表核心创新点 项目核心亮点(“老年人”非得在地上穿梭也行,恐高嘛) 产品定位:SkyLove 情侣飞行器 专为 18-25 岁青少年情侣设计 集科技感、时尚性、情感表达于一体 价格…...

Python实现对比两个Excel表某个范围的内容并提取出差异

Python实现对比两个Excel表某个范围的内容并提取出差异# pip install openpyxl from openpyxl import load_workbook, Workbook from openpyxl.utils.cell import coordinate_from_string, column_index_from_string, get_column_letter from openpyxl.styles import Font, Pat…...

软件工程实践一:Git 使用教程(含分支与 Gitee)

目录目标一、快速上手1. Windows 安装 Git2. 初始化 / 克隆二、核心概念速览三、常用命令清单1) 查看状态与差异2) 添加与提交3) 历史与回溯4) 撤销与恢复(Git 2.23+ 推荐新命令)5) 忽略文件四、分支与合并(Branch & Merge)1) 创建与切换2) 更新主干与合并3) 推送与合并…...

我用AI给自己做了一整套专属表情包!攻略

本文分享用AI制作专属表情包的实用教程。群聊斗图,关键时刻找不到图,真的太憋屈了! 别再到处“偷”图了,最近发现用AI给自己做表情包,超简单,而且特别爽!😎1️⃣灵感和准备 一切都从一张照片开始。找一张光线好的高清正脸自拍,这是你所有表情包的“灵魂”!越清晰,A…...

20250916 之所思 - 人生如梦

20250916 之所思做的不好的地方:1. 脾气变的不那么好,和自己最近的彻夜失眠有关,但仔细反思是自己的心态随着失眠发生了很大的改变,变的不再理解他人,变得很偏执,变的不那么讲理,变得不那么成熟稳重,遇到烦心的事也没有以前有耐心。缺点太多了,多站在对方的角度看问题…...

Vue3项目开发专题精讲【左扬精讲】—— 在线教育网站系统(基于 Vue3+TypeScript+Vite 的在线教育网站系统系统设计与实现)

Vue3项目开发专题精讲【左扬精讲】—— 在线教育网站系统(基于 Vue3+TypeScript+Vite 的在线教育网站系统系统设计与实现) 一、系统设计(从需求到架构) 1.1、需求分析(明确核心目标与用户场景)1.2、系统功能设计(7个核心页面) 1.2、系统功能结构图 二、​商城网站系统运…...

20250915

20250915T1 ZZH 的游戏 二分答案之后,两个点轮流跳到当前能跳到的最小点。如果没法跳了且不都在 \(1\),那么无解。容易发现这是对的,可以通过建重构树维护。然后发现二分答案不是必要的,只需要每次没法跳的时候手动开大答案即可。复杂度瓶颈在建重构树的并查集。代码 #inc…...

Python Socket网络编程(4)

协程 微线程,切换执行 比如遇到IO等待的时候可以自动切换,提升线程利用率,多用在IO等待你想干点别的...

今日学习 dos命令和Java基础语法

今日学习 dos命令和Java基础语法 dos命令 常用快捷键ctrl+c 复制 ctrl+v粘贴 ctrl+x剪切 ctrl+z撤销 ctrl+s保存 ctrl+f查找 ctrl+shift+ESC 任务管理器(电脑死机时,可用于结束进程,explore,桌面进程) shift+delete永久删除 ALT+F4关闭窗口 ALT+TAB切换窗口/程序 win+R命令…...

课前问题列表

1.3 课前问题列表 方法相关问题static void changeStr(String x) {x = "xyz";}static void changeArr(String[] strs) {for (int i = 0; i < strs.length; i++) {strs[i] = strs[i]+""+i;}}public static void main(String[] args) { String x = &qu…...

switch中初始化变量

在 C++ 的 switch 语句中,switch 是 “跳转式” 控制结构,case 标签并非独立的语句块,若直接在 case 下初始化变量,可能导致变量作用域混乱、未初始化就被使用等问题,甚至触发编译错误。 1.跨 case 的变量作用域冲突 在某个 case 中初始化的变量,其作用域会覆盖后续 case…...

office2024免费永久激活安装包下载安装教程包含(下载安装配置激活)

大家好!最近总有人问我 Office 2024 专业增强版怎么装,今天特意整理这份超详细的 Office 2024 专业增强版下载安装教程,从电脑能不能装、在哪安全下载,到一步步安装激活,再到遇到问题怎么解决,全给大家说清楚,新手也能跟着装成功,建议收藏备用!目录一、Office 2024 专…...

vue2和vue3一时转不过来

以下是 Vue2 和 Vue3 在核心语法和功能上的主要区别,结合具体代码示例说明:一、响应式数据定义方式 1. ​​数据声明位置​​ // Vue2 选项式 API export default {data() {return {name: iwen,list: []}} }// Vue3 组合式 API import { ref, reactive } from vue export def…...

怎么查询电脑的登录记录及密码更改情况? - Li

怎么查询电脑的登录记录及密码更改情况? 写这个随笔的源头是我在一家公司上班,他们自己电脑打不开,一口咬定办公室的电脑莫名其妙打不开了,是我在被他们违规辞退后设定的密码,另将监控室电脑加密,且未告知公司任何人。 莫名其妙,因为本来就没设密码啊!(躺倒) 当然最后…...

C语言结构体中的内存对齐

C语言结构体内存对齐 在C语言编程中,结构体是一种非常重要的数据类型,它允许我们将不同类型的数据组合在一起。然而,当涉及到结构体在内存中的存储时,有一个关键的概念——内存对齐,这往往容易被忽视,但却对程序的性能和内存使用有着重要影响。 一、结构体大小计算的“理…...

该练习 DP 了!

区间DP 洛谷P3147Problem 定义 \(f[i][j]\) 存储从左端点 \(j\) 开始,能合并出 \(i\) 的右端点位置,将其设为 \(k\) 。 下面我们推转移方程。从题意可以看出,两个相邻的 \(i-1\) 能够合并出 \(i\) 。那么在 \(f[i][j]\) 后所对应的就是 \(f[i][k]\),这两个 \(i\)合并能够得…...

本周计划

周三: 上午 8:00~10:30 新领军 10:30~11:30 ZR NOIPD3 T4 下午模拟赛 晚上新领军习题课两节 周四: 上午 8:00~11:30 补好题分享 2 道 下午 2:00~4:30 补模拟赛 晚上 6:30~8:00 补模拟赛或好题分享 周五 上午 8:00~11:30 补好题分享 2 道 下午 2:00~5:30 准备下个周好题分享,…...

PPT文件太大?一招「无损」压缩图片,秒变传输小能手!

本文介绍的方法基于「PPT百科网」提供的在线分析工具,可智能评估并指导压缩过程,确保最佳效果。 PPT文件体积暴涨,99%的根源在于内部图片分辨率过高。直接使用PowerPoint自带的“压缩图片”功能虽然简单,但如同一刀切,可能导致在其他设备上播放时图片模糊,风险不可控。 「…...

9月16模拟赛

题目很难 主要是没有找对策略 就是没有及时去想部分分 怎么说呢 实力太弱 其实部分分拿完也会有个不错的成绩 无所谓 csp rp++!...

C++ 单例 Meyers Singleton(迈耶斯单例)

Meyers Singleton(迈耶斯单例)是 C++ 中实现单例模式的一种简洁高效的方法,由 C++ 专家 Scott Meyers 提出。其核心原理是利用局部静态变量的初始化特性保证单例的唯一性和线程安全性(C++11 及以后标准)。 1、核心原理局部静态变量的初始化特性 在 C++ 中,函数内的局部静…...

EF Core 与 MySQL:查询优化详解

EF Core 与 MySQL:查询优化详解 1. 使用 AsNoTracking 提高查询性能 基本用法// 常规查询(会跟踪实体变更) var products = context.Products.Where(p => p.Price > 100).ToList();// 使用 AsNoTracking(不跟踪实体变更,性能更好) var products = context.Product…...

短视频营销运营资深导师张伽赫,东莞绳木传媒创始人

东莞绳木传媒创始人张伽赫,短视频营销运营领域的资深导师。凭借其对行业趋势的敏锐洞察与实战经验,已成为企业数字化转型中短视频营销领域的标杆人物。他深耕短视频赛道多年,不仅构建了从账号定位、内容创作到流量转化的完整方法论,更通过绳木传媒为企业提供“AI+短视频”全…...

20250913

T4。T1 查询被包含的区间 将区间视为平面上的点 \((l, r)\),则每次询问的合法范围容易表示,是一个三角形。可以通过两步容斥转化为一个一维偏序和三个二维偏序。直接做就好了。代码 #include <iostream> #include <algorithm> #define lowbit(x) ((x) & (-(…...

9.13日总结

整体总结: 1.在自己的大样例出问题时要及时找老师考大样例 不要对着不对的大样例虚空调试 2.在考场上要自己造大样例 要造极限数据 这样可以防止数组越界 3.在数据不超过5e6的情况下 单log都是可以过的 只要极限数据跑的不是很慢就不用担心常数问题 4.在考场上要留一个小时以上…...

哇哇哇下雨了!——2025 . 9 . 16

哇哇哇下雨了! 感觉我从小就不喜欢晴天,反而钟爱雨天,其实每次下雨我心里就在想“哇哇哇又下雨了”。 可能跟打小的性格有关,也可能跟那个人有关。 当时我写了好多关于雨的小诗,无论是给她的还是给我自己的,内容也想不起来几句了。那会儿虽然每天的生活是无味的严苛的,但…...

奇思妙想(胡思乱想)

前言: 作为一个想象力 丰富 夸张的人,总有一些奇思怪想,浅浅记录一下呀~~ 可能会很奇怪以及不符合实际,毕竟是想象的【逃】 正文:圈养的猪会不会觉得人类的是自己的奴隶(因为一直好吃好喝的供着它们) 睡觉会不会就是脑电波以第一视角或第三视角的方式观察到平行宇宙的自…...

AI Compass前沿速览:GPT-5-Codex 、宇树科技世界模型、InfiniteTalk美团数字人、ROMA多智能体框架、混元3D 3.0

AI Compass前沿速览:GPT-5-Codex 、宇树科技世界模型、InfiniteTalk美团数字人、ROMA多智能体框架、混元3D 3.0AI Compass前沿速览:GPT-5-Codex 、宇树科技世界模型、InfiniteTalk美团数字人、ROMA多智能体框架、混元3D 3.0 AI-Compass 致力于构建最全面、最实用、最前沿的AI…...

C++中set与map的自定义排序方法详解

在C++标准模板库(STL)中,set和map是两种常用的关联容器,它们默认按照键的升序进行排序。但在实际开发中,我们经常需要根据特定需求对元素进行自定义排序。本文将详细介绍如何为set和map实现自定义排序。 默认排序行为 在深入了解自定义排序之前,我们先看一下set和map的默认…...

id

卷姬神经瓦特 2025.09.16本文来自博客园,作者:transformert,转载请注明原文链接:https://www.cnblogs.com/ac-network/p/19095883...

【汇总】Qt常用模块头文件

一、变量、命令、参数排序 项目.pro文件 模块导入 include 文件 中文说明 备注、示例ABCDEFGHIJKLM#include <QMessageBox> 信息提示窗口QMessageBox::about(this, "关于",“关于说明”);NOPQRSQT += serialport #include <QSerialPort> 串口控制类#inc…...

Advanced Algorithm —— Hashing and Sketching

Birthday Problem \(m\) 个人,\(n\) 天,没有两个人生日相同的概率为: \[\displaystyle{ \begin{align*} \Pr[\mathcal{E}]=\left(1-\frac{1}{n}\right)\cdot \left(1-\frac{2}{n}\right)\cdots \left(1-\frac{m-1}{n}\right) &= \prod_{k=1}^{m-1}\left(1-\frac{k}{n}\r…...

CF2136 Codeforces Round 1046 (Div. 2) 补题

题目标签B笛卡尔树的应用C有思维难度的 dp / 递推D交互题 利用曼哈顿距离反过来解坐标:二元线性方程组 考虑“问最值/极限情况”E二分图,边双连通分量 两条路径 -> 环 异或运算的性质 (见题解)题解:E. By the Assignment观察1:对于本题,每个边双连通分量内部的点权可…...

【IEEE出版、EI检索稳定】第四届云计算、大数据应用与软件工程国际学术会议(CBASE 2025)

第四届云计算、大数据应用与软件工程国际学术会议(CBASE 2025) 2025 4th International Conference on Cloud Computing, Big Data Application and Software Engineering 在这里看会议官网详情 2025年10月24-26日丨中国-成都(线上同步举办) 截稿日期:看官网 检索类型:IE…...

缺省源

自用,你不见得会用。 快读:点击查看代码 #define getc() getchar_unlocked() #define putc(a) putchar_unlocked(a) #define en_ putc(\n) #define e_ putc( )template<class T> inline T in() { T n = 0; char p = getc();while (p < -) p = getc();bool f = p == …...

97. 交错字符串

题目链接:97. 交错字符串 - 力扣(LeetCode)‘解析:二维dp dp[i][j]代表s1前i个和s2前j个是否能组成s3的i+j个 状态转移方程就很简单了, 但这一题要求空间限制,可以观察到dp其实只记录一维就可以,因为用到了i-1或者j-1class Solution { public:bool isInterleave(string …...

MODint(自动取模)

主要来自here,我就只是补充了点东西,修改了一点东西,改了点 re 判断。 建议和我的快读一同使用,兼容的。 in,out兼容,不过建议in(a.val),快一些。同理,建议out(a.val) 不行的话也有流输入输出的兼容。 除法是 \(O(\log mod)\) 的,嫌慢可以自行修改 inv() 函数内容。 t…...

BFD实验

动态bfd+OSPF: bfd q ospf 1 bfd all-interfaces enable net .... net .......

2025.9.16——卷1阅读程序1、2

阅读程序2 vector容量与大小 容量表示在不申请内存的情况下vector还可以添加多少元素,通常超过限制之后容量会增加>=1,具体看算法实现 大小表示vector中有多少元素 .assign(n,val) 将vector的内容替换为n个val值的元素...