本文目錄一覽:
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'了
希望對你有幫助

