本文目录一览:
linux文件锁定被使用
一、什么是文件锁定
对于锁这个字,大家一定不会陌生,因为我们生活中就存在着大量的锁,它们各个方面发挥着它的作用,现在世界中的锁的功能都可归结为一句话,就是阻止某些人做某些事,例如,门锁就是阻止除了屋主之外的人进入这个房子,你进入不到这个房子,也就不能使用房子里面的东西。
而因为程序经常需要共享数据,而这通常又是通过文件来实现的,试想一个情况,A进程正在对一个文件进行写操作,而另一个程序B需要对同一个文件进行读操作,并以读取到的数据作为自己程序运行时所需要的数据,这会发生什么情况呢?进程B可能会读到错乱的数据,因为它并不知道另一个进程A正在改写这个文件中的数据。
为了解决类似的问题,就出现了文件锁定,简单点来说,这是文件的一种安全的更新方式,当一个程序正在对文件进行写操作时,文件就会进入一种暂时状态,在这个状态下,如果另一个程序尝试读这个文件,它就会自动停下来等待这个状态结束。Linux系统提供了很多特性来实现文件锁定,其中最简单的方法就是以原子操作的方式创建锁文件。
用回之前的例子就是,文件锁就是当文件在写的时候,阻止其他的需要写或者要读文件的进程来操作这个文件。
二、创建锁文件
创建一个锁文件是非常简单的,我们可以使用open系统调用来创建一个锁文件,在调用open时oflags参数要增加参数O_CREAT和O_EXCL标志,如file_desc = open("/tmp/LCK.test", O_RDWR|O_CREAT|O_EXCL, 0444);就可以创建一个锁文件/tmp/LCK.test。O_CREAT|O_EXCL,可以确保调用者可以创建出文件,使用这个模式可以防止两个程序同时创建同一个文件,如果文件(/tmp/LCK.test)已经存在,则open调用就会失败,返回-1。
如果一个程序在它执行时,只需要独占某个资源一段很短的时间,这个时间段(或代码区)通常被叫做临界区,我们需要在进入临界区之前使用open系统调用创建锁文件,然后在退出临界区时用unlink系统调用删除这个锁文件。
注意:锁文件只是充当一个指示器的角色,程序间需要通过相互协作来使用它们,也就是说锁文件只是建议锁,而不是强制锁,并不会真正阻止你读写文件中的数据。
可以看看下面的例子:源文件文件名为filelock1.c,代码如下:
#include unistd.h #include stdlib.h #include stdio.h #include fcntl.h #include errno.h int main() { const char *lock_file = "/tmp/LCK.test1"; int n_fd = -1; int n_tries = 10; while(n_tries--) { //创建锁文件 n_fd = open(lock_file, O_RDWR|O_CREAT|O_EXCL, 0444); if(n_fd == -1) { //创建失败 printf("%d - Lock already present ", getpid()); sleep(2); } else { //创建成功 printf("%d - I have exclusive access ", getpid()); sleep(1); close(n_fd); //删除锁文件,释放锁 unlink(lock_file); sleep(2); } } return 0; }
同时运行同一个程序的两个实例,运行结果为:

从运行的结果可以看出两个程序交叉地对对文件进行锁定,但是真实的操作却是,每次调用open函数去检查/tmp/LCK.test1这个文件是否存在,如果存在open调用就失败,显示有进程已经把这个文件锁定了,如果这个文件不存在,就创建这个文件,并显示许可信息。但是这种做法有一定的缺憾,我们可以看到文件/tmp/LCK.test1被创建了很多次,也被unlink删除了很多次,也就是说我们不能使用已经事先有数据的文件作为这种锁文件,因为如果文件已经存在,则open调用总是失败。
给我的感觉是,这更像是一种对进程工作的协调性安排,更像是二进制信号量的作用,文件存在为0,不存在为1,而不是真正的文件锁定。
三、区域锁定
我们还有一个问题,就是如果同一个文件有多个进程需要对它进行读写,而一个文件同一时间只能被一个进程进行写操作,但是多个进程读写的区域互不相关,如果总是要等一个进程写完其他的进程才能对其进行读写,效率又太低,那么是否可以让多个进程同时对文件进行读写以提高数据读写的效率呢?
为了解决上面提到的问题,和出现在第二点中的问题,即不能把文件锁定到指定的已存在的数据文件上的问题,我们提出了一种新的解决方案,就是区域锁定。
简单点来说,区域锁定就是,文件中的某个部分被锁定了,但其他程序可以访问这个文件中的其他部分。
然而,区域锁定的创建和使用都比上面说的文件锁定复杂很多。
1、创建区域锁定
在Linux上为实现这一功能,我们可以使用fcntl系统调用和lockf调用,但是下面以fcntl系统调用来讲解区域锁定的创建。
fctnl的函数原理为:
int fctnl(int fildes, int command, ...);
它对一个打开的文件描述进行操作,并能根据command参数的设置完成不同的任务,它有三个可选的任务:F_GETLK,F_SETLK,F_SETLKW,至于这三个参数的意义下面再详述。而当使用这些命令时,fcntl的第三个参数必须是一个指向flock结构的指针,所以在实际应用中,fctnl的函数原型一般为:int fctnl(int fildes, int command, struct flock *flock_st);
2、flock结构
准确来说,flock结构依赖具体的实现,但是它至少包括下面的成员:
short l_type;文件锁的类型,对应于F_RDLCK(读锁,也叫共享锁),F_UNLCK(解锁,也叫清除锁),F_WRLCK(写锁,也叫独占锁)中的一个。
short l_whence;从文件的哪个相对位置开始计算,对应于SEEK_SET(文件头),SEEK_CUR(当前位置),SEEK_END(文件尾)中的一个。
off_t l_start;从l_whence开始的第l_start个字节开始计算。
off_t l_len;锁定的区域的长度。
pid_t l_pid;用来记录参持有锁的进程。
成员l_whence、l_start和l_len定义了一个文件中的一个区域,即一个连续的字节集合,例如:
struct flock region;
region.l_whence = SEEK_SET;
region.l_start = 10;
region.l_len = 20;
则表示fcntl函数操作锁定的区域为文件头开始的第10到29个字节之间的这20个字节。
3、文件锁的类型
从上面的flock的成员l_type的取值我们可以知道,文件锁的类型主要有三种,这里对他们进行详细的解说。
F_RDLCK:
从它的名字我们就可以知道,它是一个读锁,也叫共享锁。许多不同的进程可以拥有文件同一(或重叠)区域上的读(共享)锁。而且只要任一进程拥有一把读(共享)锁,那么就没有进程可以再获得该区域上的写(独占)锁。为了获得一把共享锁,文件必须以“读”或“读/写”方式打开。
简单点来说就是,当一个进程在读文件中的数据时,文件中的数据不能被改变或改写,这是为了防止数据被改变而使读数据的程序读取到错乱的数据,而文件中的同一个区域能被多个进程同时读取,这是容易理解的,因为读不会破坏数据,或者说读操作不会改变文件的数据。
F_WRLCK:
从它的名字,我们就可以知道,它是一个写锁,也叫独占锁。只有一个进程可以在文件中的任一特定区域拥有一把写(独占)锁。一旦一个进程拥有了这样一把锁,任何其他进程都无法在该区域上获得任何类型的锁。为了获得一把写(独占)锁,文件也必须以“读”或“读/写”方式打开。
简单点来说,就是一个文件同一区域(或重叠)区域进在同一时间,只能有一个进程能对其进行写操作,并且在写操作进行期间,其他的进程不能对该区域进行读取数据。这个要求是显然易见的,因为如果两个进程同时对一个文件进行写操作,就会使文件的内容错乱起来,而由于写时会改变文件中的数据,所以它也不允许其他进程对文件的数据进行读取和删除文件等操作。
F_UNLCK:
从它的名字就可以知道,它用于把一个锁定的区域解锁。
4、不同的command的意义
在前面说到fcntl函数的command参数时,说了三个命令选项,这里将对它们进行详细的解说。
F_GETLK命令,它用于获取fildes(fcntl的第一个参数)打开的文件的锁信息,它不会尝试去锁定文件,调用进程可以把自己想创建的锁类型信息传递给fcntl,函数调用就会返回将会阻止获取锁的任何信息,即它可以测试你想创建的锁是否能成功被创建。fcntl调用成功时,返回非-1,如果锁请求可以成功执行,flock结构将保持不变,如果锁请求被阻止,fcntl会用相关的信息覆盖flock结构。失败时返回-1。
所以,如果调用成功,调用程序则可以通过检查flock结构的内容来判断其是否被修改过,来检查锁请求能否被成功执行,而又因为l_pid的值会被设置成拥有锁的进程的标识符,所以大多数情况下,可以通过检查这个字段是否发生变化来判断flock结构是否被修改过。
使用F_GETLK的fcntl函数调用后会立即返回。
举个例子来说,例如,有一个flock结构的变量,flock_st,flock_st.l_pid = -1,文件的第10~29个字节已经存在一个读锁,文件的第40~49个字节中已经存在一个写锁,则调用fcntl时,如果用F_GETLK命令,来测试在第10~29个字节中是否可以创建一个读锁,因为这个锁可以被创建,所以,fcntl返回非-1,同时,flock结构的内容也不会改变,flock_st.l_pid = -1。而如果我们测试第40~49个字节中是否可以创建一个写锁时,由于这个区域已经存在一个写锁,测试失败,但是fcntl还是会返回非-1,只是flock结构会被这个区域相关的锁的信息覆盖了,flock_st.l_pid为拥有这个写锁的进程的进程标识符。
F_SETLK命令,这个命令试图对fildes指向的文件的某个区域加锁或解锁,它的功能根据flock结构的l_type的值而定。而对于这个命令来说,flock结构的l_pid字段是没有意义的。如果加锁成功,返回非-1,如果失败,则返回-1。使用F_SETLK的fcntl函数调用后会立即返回。
F_SETLKW命令,这个命令与前面的F_SETLK,命令作用相同,但不同的是,它在无法获取锁时,即测试不能加锁时,会一直等待直到可以被加锁为止。
5、例子
看了这么多的说明,可能你已经很乱了,就用下面的例子来整清你的思想吧。
源文件名为filelock2.c,用于创建数据文件,并将文件区域加锁,代码如下:
#include unistd.h #include stdlib.h #include stdio.h #include fcntl.h int main() { const char *test_file = "test_lock.txt"; int file_desc = -1; int byte_count = 0; char *byte_to_write = "A"; struct flock region_1; struct flock region_2; int res = 0; //打开一个文件描述符 file_desc = open(test_file, O_RDWR|O_CREAT, 0666); if(!file_desc) { fprintf(stderr, "Unable to open %s for read/write ", test_file); exit(EXIT_FAILURE); } //给文件添加100个‘A’字符的数据 for(byte_count = 0; byte_count 100; ++byte_count) { write(file_desc, byte_to_write, 1); } //在文件的第10~29字节设置读锁(共享锁) region_1.l_type = F_RDLCK; region_1.l_whence = SEEK_SET; region_1.l_start = 10; region_1.l_len = 20; //在文件的40~49字节设置写锁(独占锁) region_2.l_type = F_WRLCK; region_2.l_whence = SEEK_SET; region_2.l_start = 40; region_2.l_len = 10; printf("Process %d locking file ", getpid()); //锁定文件 res = fcntl(file_desc, F_SETLK, ®ion_1); if(res == -1) { fprintf(stderr, "Failed to lock region 1 "); } res = fcntl(file_desc, F_SETLK, ®ion_2); if(res == -1) { fprintf(stderr, "Failed to lock region 2 "); } //让程序休眠一分钟,用于测试 sleep(60); printf("Process %d closing file ", getpid()); close(file_desc); exit(EXIT_SUCCESS); }
下面的源文件filelock3.c用于测试上一个文件设置的锁,测试可否对两个区域都加上一个读锁,代码如下:
#include unistd.h #include stdlib.h #include stdio.h #include fcntl.h int main() { const char *test_file = "test_lock.txt"; int file_desc = -1; int byte_count = 0; char *byte_to_write = "A"; struct flock region_1; struct flock region_2; int res = 0; //打开数据文件 file_desc = open(test_file, O_RDWR|O_CREAT, 0666); if(!file_desc) { fprintf(stderr, "Unable to open %s for read/write ", test_file); exit(EXIT_FAILURE); } //设置区域1的锁类型 struct flock region_test1; region_test1.l_type = F_RDLCK; region_test1.l_whence = SEEK_SET; region_test1.l_start = 10; region_test1.l_len = 20; region_test1.l_pid = -1; //设置区域2的锁类型 struct flock region_test2; region_test2.l_type = F_RDLCK; region_test2.l_whence = SEEK_SET; region_test2.l_start = 40; region_test2.l_len = 10; region_test2.l_pid = -1; //
三、解空锁问题
如果我要给在本进程中没有加锁的区域解锁会发生什么事情呢?而如果这个区域中其他的进程有对其进行加锁又会发生什么情况呢?
如果一个进程实际并未对一个区域进行锁定,而调用解锁操作也会成功,但是它并不能解其他的进程加在同一区域上的锁。也可以说解锁请求最终的结果取决于这个进程在文件中设置的任何锁,没有加锁,但对其进行解锁得到的还是没有加锁的状态。
githubmarkdown以源码方式显示了
注意:Windows环境下载时,分为User版和System版(推荐),User版只能安装在C盘的用户文件夹下,System版可以自定义安装位置,用户可以安装需求选择下载哪个版本。
设置中文
安装好VS Code后,软件默认为英文,以下步骤可以将其设置为中文。
选择View - Command Palette,或使用快捷键Ctrl+Shift+P,搜索configure language,然后选择Configure Display Language,然后选择zh-cn,如下图。
在这里插入图片描述
注意: 若选择Configure Display Language后,未出现上图所示选项,而是出现如下图的json文件编辑页面,则可能为旧版的VS Code,将json文件中的locale后面的en改为zh-cn,然后按照步骤3中安装Chinese (Simplified)Language Pack扩展。
在这里插入图片描述
若没有zh-cn,可以选择Install additional languages,然后安装扩展包Chinese (Simplified) Language Pack,然后重复步骤1。
也可以先在View - Extensions中安装Chinese (Simplified)Language Pack中文简体语言包扩展,如下图第1个扩展,然后进行步骤1。
在这里插入图片描述
安装扩展
在查看 - 扩展中可以查看、设置、启用、禁用、卸载已安装扩展,即对已安装扩展进行管理,同时可以搜索并安装各种扩展,如下图。
在这里插入图片描述
编辑Markdown文档
在VS Code中打开或新建.md格式的文件即可进行编辑(在VS Code中新建文件时可能需要先保存为.md格式文件),点击右上角的预览按钮可以进行实时预览。下图第一个按钮即为预览按钮。
在这里插入图片描述
配合Markdown使用的扩展
推荐的扩展套装:
基于Markdown Preview Enhanced扩展预览窗口(推荐):Markdown Preview Enhanced 和 Prince软件 + markdownlint + Mermaid Markdown Syntax Highlighting + Maridown PDF(可选) + vscode-pdf(可选)
优点:支持各种CSDN博客特殊语法,如:mermaid绘图,注脚,注释,等等。而且预览窗口不受VS Code软件深色主题的影响,更加形象的展示所编写文件的pdf文档样式。
基于原生预览窗口:markdownlint + Markdown+Math + Mermaid Markdown Syntax Highlighting + Markdown Preview Mermaid Support + Maridown PDF + vscode-pdf(可选)
优点:预览窗口反应快速,无需安装额外的预览扩展,主题可以跟随VS Code软件的深色主题。
缺点:部分特殊语法无法得到支持。
以下为各个扩展的详情介绍:
markdownlint:一个好用的 Markdown 格式检查扩展,它规定了许多规则并实时对文档进行检查,防止一些语法错误,同时维持文档风格的统一,使用此工具有助于形成一个良好的写作习惯和规范。
Markdown Preview Enhanced:一个很好用的完善预览功能的插件,可以更加形象的展示所编写文件的pdf文档样式。优点是支持LaTeX数学公式和Mermaid图表等内容的显示。
安装后,你会发现工作区的右上角多了一个预览按钮,这个按钮就是Markdown Preview Enhanced插件产生的,如下图。直接右键.md文件的页面也可以开启Markdown Preview Enhanced。
在这里插入图片描述
注意:右键Markdown Preview Enhanced预览页面也有一些选项,如下图。Open in Browser是在浏览器中打开预览,HTML是打印成HTML文件,PDF是打印成PDF文件(此选项需额外安装Prince软件,VS Code扩展库中没有,安装方法见后文)。
在这里插入图片描述
安装Prince软件:进入Prince官网,点击下载,选择对应的版本进行下载并安装。然后添加环境变量,右键我的电脑-属性-高级系统设置-环境变量-系统变量-Path-编辑,新建一条Prince安装路径\engine\bin即可。然后重启VS Code。
Markdown All in One:集成了各种功能,同时也支持LaTeX数学公式(在扩展设置中启用基本的数学支持选项可以开启与关闭该功能),但貌似没有显示Mermaid图表和打印PDF的功能。个人建议,若启用Markdown+Math扩展,则不必启用此扩展。
Markdown+Math:使VS Code原生的Markdown预览窗口支持显示LaTeX数学公式。可以与Markdown All in One扩展同时使用,同时使用时,LaTeX公式显示风格以Markdown+Math为标准。
Mermaid Markdown Syntax Highlighting:支持Mermaid图表代码高亮,但无法在原生预览窗口显示。
Markdown Preview Mermaid Support:支持原生预览窗口显示Mermaid图表。
Maridown PDF:可以简单的将编写的.md文件转换成其他格式的文件,右键.md文件的页面可以进行转换,如下图。生成的文件将会直接保存在.md文件的文件夹下。但不支持LaTeX数学公式和Mermaid图表等内容的显示。
在这里插入图片描述
vscode-pdf:若希望在VS Code中直接打开并浏览pdf格式文件,可以通过安装该插件来达到该目的。
Markdown Pad 2
介绍
Markdown是一种可以使用普通文本编辑器编写的标记语言,通过简单的标记语法,它可以使普通文本内容具有一定的格式。而Markdown Pad 2 便是编辑Markdown语言的一款编辑器,其功能强大,便捷,速度快,无广告,而且还可以进行个性化设置。下面介绍一下Windows系统下,该工具的安装与配置方法。
安装
进入官网:官网链接,然后点击Download MarkdownPad;或者直接点击该链接,下载链接,会立刻开始下载。
运行上一步骤下载到的exe文件,开始安装,并完成安装。
注意:Win10若提示HTML渲染组件出错,错误的表现形式为,不能实时预览Markdown生成的HTML页面。则需要安装awesomium_sdk,下载地址:Download awesomium_v1.6.6_sdk_win.exe。
设置中文
Tool — Options — Editor — Language,选择中文。
Key
在初次打开软件时单击Enter Key按钮,或点击帮助—升级到MarkdownPad专业版。输入如下Email和Key。
Soar360@live.com
1
1
Key
GBPduHjWfJU1mZqcPM3BikjYKF6xKhlKIys3i1MU2eJHqWGImDHzWdD6xhMNLGVpbP2M5SN6bnxn2kSE8qHqNY5QaaRxmO3YSMHxlv2EYpjdwLcPwfeTG7kUdnhKE0vVy4RidP6Y2wZ0q74f47fzsZo45JE2hfQBFi2O9Jldjp1mW8HUpTtLA2a5/sQytXJUQl/QKO0jUQY4pa5CCx20sV1ClOTZtAGngSOJtIOFXK599sBr5aIEFyH0K7H4BoNMiiDMnxt1rD8Vb/ikJdhGMMQr0R4B+L3nWU97eaVPTRKfWGDE8/eAgKzpGwrQQoDh+nzX1xoVQ8NAuH+s4UcSeQ==
1
1
个性化设置
菜单栏 — 工具 — 选项
Markdown — GitHub 风格 Markdown (离线)
样式表 — Markdownpad-github.css
文件 — 在导出的PDF文件中包含CSS背景
Markdown与HTML的联系
Markdown支持HTML的大部分标签,但反之HTML不支持Markdown语法;即Markdown兼容HTML。例如换行标签br,键盘文本kbd,预格式文本pre,上标sup,下标sub,等等。更多标签和用法请参照HTML标签 。
例子:
键盘文本-复制的快捷键:kbdCtrl/Command/kbd + kbdC/kbd
显示:
Ctrl/Command + C
Markdown中支持HTML的大部分字符实体,如大于号: ,显示为。更多HTML字符实体请参照HTML字符实体 。
编辑技巧
快捷键
在编辑页面可以适当的使用快捷键提升效率。以下为CSDN的快捷键,其中有些是可以通用于各个编辑器的。
CSDN快捷键:
撤销:Ctrl/Command + Z
重做:Ctrl/Command + Y
加粗:Ctrl/Command + B
斜体:Ctrl/Command + I
标题:Ctrl/Command + Shift + H
无序列表:Ctrl/Command + Shift + U
有序列表:Ctrl/Command + Shift + O
待办列表:Ctrl/Command + Shift + C
插入代码:Ctrl/Command + Shift + K
插入链接:Ctrl/Command + Shift + L
插入图片:Ctrl/Command + Shift + G
列表
当使用顺序列表时,按回车会自动生成序号,想中断排序,再按一次回车即可。
在顺序列表的编号后面按回车,不会打乱编号的顺序。
当使用列表后,缩进中断时,可以使用Tab进行缩进。
标记失效
在使用Markdown标记语言时,一些标记后需要加空格才会生效,如标题标记:# 。
一些标记的前面需要有回车才会生效,如分隔符:--- 。
一些字体标记,当结束标记前的字符为标点符号时可能会失效。
例如:**标点符号。**是句号。
显示:**标点符号。**是句号。
解决方案:在结束标记**后加空格即可,其他字体标记同理。
例如:**标点符号。** 是句号。
显示:标点符号。 是句号。
页面内跳转
由于Markdown目前没有实现页面内跳转的方法,故可以使用HTML的方法进行页面内跳转,因为Markdown支持HTML。值得一提的是,跳转到锚点时,可以使用Markdown的链接语法进行跳转。
注意: 示例中锚点的h1标签可以换成任何其他标签,如text标签等。
纯HTML示例:
!-- 跳转到锚点 --
a href="#1"锚点目标/a
!-- 创建锚点 --
h1 id="1"锚点/h1
1
2
3
4
1
2
3
4
HTML创建锚点+Markdown跳转示例:
跳转到锚点:[锚点目标](锚点id '标题')
创建锚点(同上):h1 id="1"锚点/h1
展示:
HTML语法跳转:锚点目标
Markdown语法跳转:锚点目标
锚点
CSDN博客技巧
CSDN目录
输入#,并按下Space后,将生成1级标题。
输入##,并按下space后,将生成2级标题。
以此类推,我们支持6级标题。有助于使用@[TOC](自定义目录标题)或@[toc](自定义目录标题)语法后生成一个有缩进的目录,可实现页内跳转。
CSDN快捷键
同编辑技巧章节的快捷键。此处省略。
自定义列表
CSDN编辑器支持,某些本地编辑器不支持。
例子(最前面要有空行):
Authors
: John
: Luke
1
2
3
1
2
3
显示:
Authors
John
Luke
注脚
CSDN编辑器支持,某些本地编辑器不支持。
注脚会按照文章的顺序自动排序。
例子:
一个具有注脚的文本。[^1]
[^1]: 注脚的解释
1
2
1
2
显示:
一个具有注脚的文本。1
注释
CSDN编辑器支持,某些本地编辑器不支持。
例子(注释词前后要有空格):
Markdown兼容 HTML 语言。
*[HTML]: 超文本标记语言
1
2
1
2
显示:
Markdown兼容 HTML 语言。
LaTeX公式
CSDN编辑器中支持LaTeX数学公式,详情请见后文的LaTeX公式章节。Typroa软件支持,设置方法详见上文的 Markdown工具 - Typroa - 设置 章节。
Mermaid制图
CSDN编辑器中支持mermaid绘图,如甘特图,UML图等。详情及具体用法请见参考文档。
参考文档:链接 。
需要注意的是:有些本地编辑器不支持mermaid绘图,但如果使用VS Code,则可以通过安装Markdown Preview Enhanced或Markdown Preview Mermaid Support扩展的方式支持,详情请见上文的 Markdown工具 - VS Code - 配合Markdown使用的扩展 章节。
下方是一些图的简单绘制方法。
甘特图
```mermaid
gantt
dateFormat YYYY-MM-DD
title Adding GANTT diagram functionality to mermaid
section 现有任务
已完成 :done, des1, 2014-01-06,2014-01-08
进行中 :active, des2, 2014-01-09, 3d
计划一 : des3, after des2, 5d
计划二 : des4, after des3, 5d
```
显示:
Mon 06
Mon 13
Mon 20
已完成
进行中
计划一
计划二
现有任务
Adding GANTT diagram functionality to mermaid
UML图
```mermaid
sequenceDiagram
张三 - 李四: 你好!李四, 最近怎么样?
李四–王五: 你最近怎么样,王五?
李四–x 张三: 我很好,谢谢!
李四-x 王五: 我很好,谢谢!
Note right of 王五: 李四想了很长时间, 文字太长了
不适合放在一行.
李四–张三: 打量着王五…
张三-王五: 很好… 王五, 你怎么样?
```
显示:
张三
李四
王五
你好!李四, 最近怎么样?
你最近怎么样,王五?
我很好,谢谢!
我很好,谢谢!
李四想了很长时间, 文字太长了
不适合放在一行.
打量着王五...
很好... 王五, 你怎么样?
张三
李四
王五
FLowchart流程图
```mermaid
flowchat
st=start: 开始
e=end: 结束
op=operation: 我的操作
cond=condition: 确认?
st-op-cond
cond(yes)-e
cond(no)-op
```
显示:
开始
我的操作
确认?
结束
yes
no
导出与导入
导出
用户可以在CSDN文章中任意编辑。完成了一篇文章的写作后, 可以在上方工具栏找到 导出按钮 ,生成一个.md文件或者.html文件进行本地保存。
导入
如果用户想加载一篇自己写过的.md文件或者.html文件,在上方工具栏可以选择导入按钮进行对应扩展名的文件导入,并继续创作。
字符实体
前言
与HTML字符实体相同,详情可参照HTML字符实体 。
空格
不换行空格,全称是 No-Break Space,它是最常见和我们使用最多的空格,大多数的人可能只接触了 ,它是按下space键产生的空格。在HTML中,如果你用空格键产生此空格,空格是不会累加的(只算1个)。要使用html实体表示才可累加,该空格占据宽度受字体影响明显而强烈。
半角空格,全称是 En Space,en是字体排印学的计量单位,为em宽度的一半。根据定义,它等同于字体度的一半(如16px字体中就是8px)。名义上是小写字母n的宽度。此空格传承空格家族一贯的特性:透明的,此空格有个相当稳健的特性,就是其占据的宽度正好是1/2个中文宽度,而且基本上不受字体影响。
全角空格,全称是 Em Space,em是字体排印学的计量单位,相当于当前指定的点数。例如,1 em在16px的字体中就是16px。此空格也传承空格家族一贯的特性:透明的,此空格也有个相当稳健的特性,就是其占据的宽度正好是1个中文宽度,而且基本上不受字体影响。
其他
显示结果 描述 实体名称 实体编号
空格
小于号
|大于号 | |
≦ |小于等于 |≤
≧ |大于等于 |≥
|和号 | |
" |引号 |" |"
’ |撇号 |' (IE不支持) |'
¢ |分 |¢ |¢
£ |镑 |£ |£
¥ |日圆 |¥ |¥
€ |欧元 |euro |€
§ |小节 |§ |§
© |版权 |© |©
® |注册商标 |® |®
™ |商标 |™ |™
× |乘号 |× |×
÷ |除号 |÷ |÷
转义字符
写法:\+字符
用途:当某些特殊字符与Markdown语法冲突时,使用转义字符可以使字符强制显示,字符实体也可用转义字符显示。
示例:
\
显示:
\=\=
显示:==
\
显示:
等等
注意:使用字符实体也可以达到一样的效果,但不常用的或记不住的字符实体建议使用转义字符。
首行缩进
缩进2个汉字大小:
使用2个 (推荐)
使用4个
使用8个
空行
连续输入2个回车,即可打出一个空行。
输入HTML表签br,即可打出一个换行。
字体
普通文本:
*强调文本* _强调文本_
**加粗文本** __加粗文本__
==标记文本==
~~删除文本~~
引用文本
1
2
3
4
5
1
2
3
4
5
显示:
强调文本 强调文本
加粗文本 加粗文本
标记文本
删除文本
引用文本
注意:强调文本即斜体文本。
组合文本:
加粗加斜:使用***或___
例子:***加粗加斜***
显示:加粗加斜
上下标
CSDN编辑器
此方法可能不适用某些本地编辑器,本地编辑器可以使用HTML方法或LaTeX公式方法。
上标:^文本^
下标:~文本~
例子:
H~2~O
2^10^
显示:
H2O
210
HTML方法
此方法比较同用,适用于各种Markdown编辑器,因为Markdown支持HTML。显示效果与CSDN编辑器相同。
上标:sup文本/sup
下标:sub文本/sub
例子:
Hsub2/subO
2sup10/sup
显示:
H2O
210
LaTeX公式方法
详情请见下文的 附录 LaTeX公式细节 - 上下标 章节。以下为简单的例子。
例子:
$x^z_{y+1}$
显示:
x y + 1 z x^z_{y+1}x
y+1
z
引用可嵌套
例子:
这是引用的内容
这是引用的内容
这是引用的内容
1
2
3
1
2
3
显示:
这是引用的内容
这是引用的内容
这是引用的内容
目录
Markdown基本语法并没有生成目录的功能,但很多平台或软件都支持生成目录,比如:CSDN博客平台、Typroa软件、等等。使用方法如下,输入下方命令即可在相应位置插入目录,该目录为Markdown文档内的标题组成的目录:
CSDN博客
@[TOC](目录名称) 或 @[toc](目录名称) 。
Typroa
[TOC] 或 [toc] 。
其他
同Typroa。
导出分页
在Markdown导出为PDF时,若想要设置分页,在Markdown文件想分页的位置输入如下HTML代码即可,再次导出即可显示分页效果。该语句已在Typroa软件中实验成功。
div style="page-break-after: always;"/div
或
div STYLE="page-break-after: always;"/div
1
2
3
1
2
3
链接
格式:[链接文本](链接地址 '链接标题')
说明:链接文本为显示的文字,链接地址为链接的网址,链接标题可以不写,是鼠标悬停在链接处显示的标题。
例子:
[Link]()
显示:
Link
列表
有序列表
示例:
1. 项目1
2. 项目2
3. 项目3
1
2
3
1
2
3
显示:
项目1
项目2
项目3
无序列表
示例:
- 项目
- 项目
- 项目
1
2
3
1
2
3
显示:
项目
项目
项目
待办列表
示例:
- [ ] 计划任务
- [x] 完成任务
1
2
1
2
显示:
计划任务
完成任务
多级列表
每写下一级有序列表或无须列表时,多缩进1个Tab(推荐)或 4 个空格。
有序多级列表示例:
1. 标题1
1. 标题1.1
1. 标题1.1.1
2. 标题1.1.2
2. 标题1.2
3. 标题1.3
2. 标题2
1
2
3
4
5
6
7
1
2
3
4
5
6
7
显示:
标题1
标题1.1
标题1.1.1
标题1.1.2
标题1.2
标题1.3
标题2
无序多级列表示例:
- 项目
- 项目
- 项目
1
2
3
1
2
3
显示:
项目
项目
项目
自定义列表
注意:CSDN编辑器支持,某些本地编辑器不支持。
例子(最前面要有空行):
Authors
: John
: Luke
1
2
3
1
2
3
显示:
Authors
John
Luke
图片
Markdown图片
插入图片格式:
在这里插入图片描述
注意: 图片替换文本是图片未显示时替换的文本,图片标题是鼠标悬停在图片上显示的文本,图片标题可不写,图片标题的引号用单引号和双引号都可以。图片地址可以是网络网址(),也可以是本地相对路径(推荐,如./images/pic1.jpg)或绝对路径。
例子:

显示:
Alt
CSDN图片
CSDN平台针对Markdown的图片语法做了特殊处理,支持调整图片的大小和对齐方式,使用方法如下:
带尺寸的图片:

显示:
Alt
居中的图片:
![Alt]()
补充:图片居左为#pic_left,图片居右为#pic_right 。
显示:
Alt
居中并且带尺寸的图片:

显示:
Alt
为了让用户更加便捷,CSDN博客增加了图片拖拽功能。
HTML图片
即使不在CSDN平台,Markdown编辑器也可以实现调整图片大小和对齐方式的功能,因为Markdown支持HTML,使用HTML语言即可,使用方法如下:
居中图片
代码:
div align=[对齐方式] !--对齐方式可以为center,left,right--
img src="图片地址" alt="替换文字" width="宽度" height="高度"
/div
1
2
3
1
2
3
示例1:居中的图片
div align=center
img src=""
/div
1
2
3
1
2
3
显示:
示例2:居中且带尺寸的图片
div align=center
img src="" width="50%"
/div
1
2
3
1
2
3
显示:
图片居中标题
无论以何种方式插入图片,都有在图片下方输入图片标题的需求,使用HTML语法即可为图片添加居中标题,使用方法如下:
在图片下方添加如下HTML代码即可:
center图片标题/center
1
1
显示:
图片标题
表格
如果表格贴近行首,则可以使用简便方式制作表格
例子:
列1 | 列2
--- | ---
值1 |值2
值3 |值4
1
2
3
4
1
2
3
4
显示:
列1 列2
值1 值2
值3 值4
若表格前有Tab缩进,则左侧的 | 需补全,否则会出现第一列不显示的状况。
例子:
| 列1 | 列2
| --- | ---
| 值1 |值2
| 值3 |值4
1
2
3
4
1
2
3
4
显示:
列1 列2
值1 值2
值3 值4
完整的表格格式。
例子:
| 列1 | 列2 | 列3 |
| :--- | :---: | ---: |
| 文本居左 | 文本居中 | 文本居右 |
1
2
3
1
2
3
显示:
列1 列2 列3
文本居左 文本居中 文本居右
注意:最左侧(第一个) | 右端最好有1或2个空格,否则可能会出现未知错误(如缺失字符,对齐失效等)。
分割线
三个或者三个以上的 - 或者 * 都可以,效果是一样的。
注意分割线前要有空行。
例子:
(空行)
---
----
***
*****
1
2
3
4
5
1
2
3
4
5
显示:
代码块
单行代码块
代码只有一行或在文本中插入时可以使用,也可以叫行中代码块,格式为:`代码` 。
例子:
`print('Hello World!)`
显示:
print('Hello World!)
多行代码块
多行代码块可以插入多行代码,且可以标记编程语言的类型,如python,可以简写成py,JavaScript可以简写成js。
格式:
```编程语言类型
代码片段
代码片段
```
例子:
```py
for i in(1,11,1):
print(‘Hello World!’,end=‘\n’)
```
显示:
for i in(1,11,1):
print('Hello World!',end='\n')
1
2
1
2
技巧
代码块前面可以使用Tab缩进,显示的代码块前端也会有缩进。
例子:
print('前面有缩进。')
1
1
在CSDN博客设置页面,可以选择一款自己喜欢的代码片高亮样式。
LaTeX数学公式
介绍
CSDN支持LaTeX公式,但有些本地编辑器可能不支持LaTeX公式,Typroa可以更改设置支持,VS Code可以通过安装扩展的方式支持,详情请见上文的 Markdown工具 章节。
LaTeX数学公式的各种细节请参见我的另一篇博客:LaTeX数学公式-详细教程 。
官方文档:
传送门:官方文档
网址:
中文教程:
传送门:中文教程
网址:
技巧:使用在线LaTeX公式编辑器,来生成LaTeX公式代码,然后复制到Markdown编辑器中,并在两边加上$或$$即可。
在线LaTeX公式编辑器网址:
插入公式
左对齐公式(行中公式):$数学公式$
居中公式(独立公式):$$数学公式$$
注意:使用$行中公式时,数学公式与$连接处不要有空格,否则公式不会显示;使用$$居中公式时,数学公式与$$连接处可以有空格。即$ 数学公式 $ 不显示公式。
注释:%为单行注释。
细节:细节请参见我的另一篇博客:LaTeX数学公式-详细教程 。
注意事项
使用$,即行中公式时,数学公式与$连接处不要有空格,否则公式不会显示。
使用$$,即居中公式时,数学公式与$$连接处可以有空格。即$ 数学公式 $ 不显示公式。
使用$$时,上方要空一行。
=不要单独打一行,否则可能会出错。
+ - * / = ( ) | , . '等符号直接在$或$$之间输入即可识别。
苹果字体在安卓系统里叫什么
IOS版的字体。ios字体在安卓叫IOS版的字体。iOS是由苹果公司开发的移动操作系统。苹果公司最早于2007年1月9日的 Macworld 大会上公布这个系统,最初是设计给iPhone使用的,后来陆续套用到iPod touch、iPad上。
类定义时如果没有定义带参数的构造函数,对象初始化能不能这样写: A a(1,2);
类中默认构造函数是无参数的,你只能 A a; 如果你想要带参数 A a(1,2 );
你就要自己写一个带参数的构造函数 如 class A {
private:
int x;
char y;
public:
A(int a, char b)
{x= a;y=b};
};
定义对象的时候,会根据你参数个数,自动调用匹配的构造函数来初始化对象的。
你定义A a;就调用默认无参构造,定义 A a(3,‘c’); 成员变量x和y就是你传入的参数 3和'c'了
希望对你有帮助