JavaShuo
欄目
標籤
C語言服務器編程必備常識
時間 2021-01-19
標籤
java
linux
程序員
shell
數據庫
緩存
服務器
網絡
多線程
併發
欄目
Java
简体版
原文
原文鏈接
入門
包含了正確的頭文件只能編譯經過,沒連接正確的庫連接會報錯。
一些經常使用的庫gcc會自動連接。
庫的缺省路徑/lib /usr/lib /usr/local/lib
不知道某個函數在那個庫能夠nm -o /lib *.so | grep 函數名
man sin 會列出包含的頭文件和連接的庫名。man 2 sin 2表示系統調用,3表示c庫函數
一旦子進程被建立,父子進程一塊兒從fork處被建立。建立子進程爲了爭奪資源。
重定向用dup2函數
kill -l查看信號種類
pthread_mutex不跨進程,ipc中的信號量跨進程,但linux不支持無名信號量。信號燈的主要用途是保護臨界資源。多進程訪問共享內存,用信號量同步。
alarm(5)5秒後向本身發送SIGALARM信號,缺省處理是結束進程,不自定義就會結束進程。經過對信號集加減信號,肯定信號屏蔽字。在信號處理程序被調用時,操做系統創建的新信號屏蔽字包括正在被遞送的信號,若是此時這個信號再次發生,將阻塞到前一個處理完,屢次發生不排隊只處理一次。 sa_mask會被加到信號屏蔽字中。
netstat -an|grep A |grep ESTABLISHED | grep B,查看ip爲A的服務器是否在端口B創建了鏈接
因爲咱們的鏈接都是常鏈接,故能夠按照客戶端與服務器端創建的鏈接端口進行判斷。
IP協議是網絡層協議,主要發送數據包。UDP基於IP協議,用在傳輸層。TCP協議創建在IP協議之上,可靠的、按順序發送的。
TCP鏈接三次握手:客戶機向服務器發包。服務器給客戶機回包。客戶機收到包,向服務器發送確認信息完成鏈接。服務器收到確認信息也完成鏈接。
ioctl能夠控制全部文件描述符的狀況。
循環服務器:UDP服務器,UDP是非面向鏈接的,沒有一個客戶機能夠總是佔着服務器。
TCP循環服務器一次只能處理一個,close後才能處理下一個。
TCP併發服務器:fork子進程來處理。建立子進程消耗資源。
併發服務器:多路IO複用。
當咱們建立一個正常的TCP套接字的時候,咱們只處理內容,不負責TCP頭部和ip頭部,本身建立頭部使用setsockopt。
網絡程序通常是多進程加上多線程。
g++參數-pg產生gprof性能信息,gprof好像是g++自帶的
(gdb)make使你能不退出gdb就能產生就從新產生可執行文件 , shell 不退出gdb就執行shell
file a.out能夠在gdb模式下載入程序。
服務器端:socket->bind->listen【創建監聽隊列,監聽socket】->【返回鏈接socket】accept【從監聽隊列取請求,成功時返回新的socket,與傳入的第一參數不一樣,標識被接受的這個鏈接】
客戶端:socket->connect
進階
linux中代替數據庫管理文件可能會出現文件數超過linux可管理數的問題。
tcpip協議族:上層協議使用下層協議提供的服務。
應用層的東西最後須要在內核中實現,會須要應用空間和內核空間的切換。
IP數據太長要分片。IP協議的核心是數據報路由。路由表、跳轉、自動更新。
socket含義ip:port。稱其爲socket地址。
字節序是按字節考慮的,和位無關。cpu累加器一次裝載4字節(32位機)。
網絡上傳的必定是大端字節序,各主機按自身狀況轉化。java虛擬機採用大端字節序。
不一樣輸入調用兩次函數,若是發現後面結果覆蓋前面結果,說明函數不可重入。函數內部若是用靜態變量存儲結果,就不可重入。
將一個地址和socket綁定稱爲給socket命名。0-1023端口普通用戶不能使用,有默認用途。
accept只是從監聽隊列中取出鏈接,不論鏈接處於何種狀態。connect(fd,..)一旦鏈接創建成功,fd就惟一標識了這個鏈接,客戶端就能夠讀寫fd和服務器通訊。
對socket執行close只減小鏈接數,fork會使引用數加1。不管如何都要終止鏈接用shutdown。
read和write一樣適用於socket。用於TCP數據流的是send recv。UDP數據是recvfrom sendto。
沒有進程讀管道的時候【例如close(fd[0])了】還往管道寫數據將引起SIGPIPE。
把STDOUT_FILENO關閉,dup(鏈接socket),這時dup返回最小可用描述符1【返回的文件描述符和原有描述符指向相同文件】,此時printf回返回給客戶端,而不是打印在屏上。
sendfile將真實文件傳給socket。splice用於在兩個文件描述符間移動數據,零拷貝,用於socket和管道之間互相定向。tee用於兩個管道之間複製數據。
IO處理單元是一個專門的接入服務器,它實現負載均衡。請求隊列是系統內部各單元之間通訊方式的抽象,通常實現爲池。
阻塞和非阻塞是對文件描述符而言的。非阻塞IO通常和IO通知機制一塊兒使用,如IO複用或SIGIO信號。IO複用自己是阻塞的,提升效率是由於同時監聽多個事件。
同步就是協同步調,按預約的前後次序進行運行。處理客戶鏈接就是讀寫描述符,就是IO,因此IO單元被定義爲接入服務器。
併發不適用於計算密集型,由於任務切換會下降效率,適用於IO密集型,如常常讀寫文件、訪問數據庫。
池就是預先靜態分配資源,到時能夠快速使用。避免了對內核的頻繁訪問。提高性能方法:池、避免數據複製、上下文切換【線程數大於cpu數時】和鎖。
讀寫鎖能夠減小鎖的粒度適用於讀多寫少的狀況。
epoll須要使用一個額外的描述符維護事件表。 EPOLLONESHOT確保只有一個線程處理某個socket。
sigaction結構體中的sa_mask設置信號掩碼,確切的說是在進程原有信號掩碼的基礎上增長信號掩碼,以指定哪些信號不能發送給本進程。
sigset_t 每一個元素的每一個位表示一個信號,因此相同的信號只能表示一次。
子進程有和父進程相同的信號掩碼,但掛起信號集【發送可是被阻塞的信號】爲空,就是說阻塞的信號是不可能發給子進程的。
應用程序使用信號集sigset_t前,應調用sigemptyset或sigfillset一次,不然信號集初始狀態不清楚。
最小時間堆能夠達到定時器的效果。
waitpid用NOHANG就是非阻塞的了。socketpair建立全雙工管道的系統調用。
對信號量的操做成爲P(傳遞,進入臨界區)V(釋放,退出臨界區)。最簡單的二進制信號量,只有0和1.用一個普通變量模擬是不行的,由於檢測和減1沒法原子完成。
linux上的線程使用clone系統調用建立的進程模擬的。
目前能夠實現跨進程的線程同步
被pthread_cancel的線程能夠決定是否容許被取消以及如何取消。
銷燬一個已經加鎖的互斥量將致使不可知的後果。互斥量屬性設置中能夠設置跨進程共享互斥量。pthread_mutexattr_setpshared()
加鎖-》pthread_cond_wait暗含解鎖,確保能檢測到條件變量的任何變化。
有些函數不可重入主要是由於內部使用了靜態變量。
多線程程序中的一個線程調用fork,只複製調fork的那個線程。互斥量的狀態也繼承,此時容易出現死鎖。
全部線程共享信號處理函數,共享進程的信號。因此須要專門線程處理全部信號。
進程池:典型的是3-10個。線程池中的線程數量應該和cpu數量差很少。通訊【通訊:傳遞數據】父子進程間可使用管道,多線程間使用一個全局數據便可。
pthread_create當線程函數是類的成員函數時,必須爲靜態函數【確保沒對象時也可使用】,因爲靜態成員函數只能訪問靜態成員,要訪問動態成員須要函數內部用單例或將類的對象做爲參數傳給函數。
SA_RESTART被信號中斷的系統調用再信號處理結束後繼續執行。
將線程池或進程池中個數減小爲1,便於調試邏輯。而後逐步增長數量,看同步。
進程類[i].fd 經過給不一樣i的fd傳遞數據,調用不一樣的進程工做。m_sub_process[i].pid=fork()【fork了maxnum次】。
線程池:線程函數一塊兒都啓動,啓動後進入while(!stop)循環,不斷的鎖隊列,取任務。
POSIX線程
只有互斥量的主人可以解鎖它。
線程的堆棧受限。
線程結束方式要麼從線程函數return,要麼調用pthread_exit,進入終止態,直到被分離或被鏈接。建立不須要鏈接的線程應該使用detachstate屬性創建線程使其自動分離。
pthread_join會阻塞調用者,直到被join的線程結束,join返回被鏈接的線程也分離,因此只能被join一次,下一次就錯誤了。
使用條件變量時必須保證若是有線程等待,則該線程等待後必然會收到信號(if/while)
條件變量可使線程處於等待狀態而不消耗資源。條件變量必須跟一個互斥變量一塊兒使用,由於條件變量就是共享的全局數據??【條件和鎖結合共同保護共享數據】status = pthread_cond_wait(&alarm_cond, &alarm_mutex);
沒有條件變量,程序員可用使用輪詢某個變量來實現停等-通知同步,可是很是消耗系統資源。
若是肯定線程不須要被Join, 則申明爲Detached能夠節省系統資源
pthread_self得到自身的ID,只能經過ID操做線程。main是主線程,主線程中止全部線程也中止,main中調用pthread_exit,這樣進程就必須等待全部線程結束才能終止。
經過向pthread_t(ID)=pthread_create傳遞線程函數地址和函數參數來建立線程。注意當前線程從pthread_create返回前,新建立的線程可能已經運行完畢了。
舀水桶相似一個互斥量:桶用來保護「舀水」臨界區【訪問臨界資源(共享數據?)的那段程序是臨界區】。或者將桶理解爲:用來確保一次只能由一我的舀水的不變量。
在訪問共享數據的代碼段周圍加鎖互斥量,則一次只能有一個線程進入該代碼段。
pthread_mutex_t表示互斥量,不能拷貝,能夠拷貝指針。
當調用pthread_mutex_lock時,若是互斥量已經被鎖住,線程將被阻塞。調用pthread_mutex_trylock時不會阻塞,會返回EBASY,能夠作其餘的事情去。
互斥量的本質是串行執行。
解決死鎖的兩種方法:一,規定加鎖順序;二,trylock若是不行回退,解鎖全部已加鎖的互斥量
sched_yield()將處理器交給另外一個等待處理的線程,若是沒有等待處理的線程。當即返回。sleep()能夠確保其餘線程有機會運行。
按照相反的順序解鎖,有助於減小線程作回退操做的可能。由於同一個線程函數中加鎖順序是同樣的。對於不一樣的線程函數順序應該不重要
線程運行於解鎖和阻塞之間時,其餘線程才能改變共享數據狀態。此時共享狀態的改變,本線程是沒法知道的。->須要條件變量。隊列滿,隊列空,滿空就是條件變量。
動態初始化的條件變量須要pthread_cond_destroy來釋放。靜態初始化的沒必要釋放。釋放前確保其餘線程不使用他。
在阻塞線程以前,條件變量等待操做pthread_cond_wait將解鎖互斥量,從新返回線程以前,會再次鎖住互斥量。子線程只在pthread_cond_wait等待的短期內能夠加鎖,修改共享數據,而後解鎖。
pthread_cond_timedwait的意思就是我在這裏等time時間,若是時間內條件變量變了,或者不變,我都要跳出while(謂詞)的循環,按狀況處理。
pthread_cond_wait和pthread_cond_signal必須同時發生才能成功。
互斥量:條件變量是 一對多的關係
當線程調用pthread_create時,她所能看到的內存值也是它創建的線程能看到的,以後的線程不必定能看到。
線程解鎖互斥量時所看到的的數據,也能被後來直接鎖住相同互斥量的線程看到。解鎖後寫入的數據,沒必要被其餘線程看見(由於那不是用來同步的數據,不必全部人看見,同步就應該加鎖)。
線程終止,取消,從啓動函數返回,pthread_exit時看到的數據,可以被鏈接該線程的其餘線程看到。終止後寫入的數據不會被看到。
線程發信號或廣播時看到的內存數據,能夠被喚醒線程看到。以後寫入的不會。
線程分配的堆棧和堆空間是私有的,除非傳給其餘線程指針。register(寄存器變量)和auto變量(大部分變量默認auto)(static變量的生命期長)中的數據可隨時讀取,像在同步程序中同樣
兩個處理器將各自的高速緩存中的數據寫入主存的順序是不必定的,即便寫到相應高速緩存的順序有前後之分。同一線程寫數據也未必按照順序刷新進內存,這使得其餘線程讀取結果不對。
鎖住互斥量->內存屏障->內存屏障->解鎖互斥量
使用線程的方式:流水線、工做組(工做線程在數據的不一樣部分操做)、C/S。
pthread_attr_setdetachstate (&_attr, PTHREAD_CREATE_DETACHED);說明在建立線程後,咱們不在須要使用線程ID。
不變量(Invariant):程序所作的一些假設,特別是指變量之間的關係。斷定條件(Predicates):描述不變量狀態的邏輯表達式。
pthread_kill(thdid, SIGTERM)給特定線程發信號
相關文章
1.
編程小白必備——主流語言C語言知識點
2.
編程語言常識
3.
C語言一些常識備忘
4.
UDP服務器端程序(C語言)
5.
編程這件小事兒之C語言篇:C語言自學必備
6.
C語言編程練手必備,C 語言快速實現五子棋!
7.
服務器後端的編程語言
8.
維護服務器平常安全有哪些必備常識
9.
在VC6.0下運行C語言程序,以及編程入門必備的常識類小知識!
10.
小螞蟻學習C語言(2)——C語言編程預備知識(上)
更多相關文章...
•
R 語言教程
-
R 語言教程
•
Git 服務器搭建
-
Git 教程
•
Spring Cloud 微服務實戰(三) - 服務註冊與發現
•
常用的分佈式事務解決方案
相關標籤/搜索
C語言編程
編程語言
知識必備
Go語言編程
C語言+網絡編程
服務器
Linux服務器
雲服務器
服務器篇
彙編語言
系統網絡
Unix
SQL
Java
Linux
快樂工作
R 語言教程
C#教程
PHP教程
服務器
C#
微服務
0
分享到微博
分享到微信
分享到QQ
每日一句
每一个你不满意的现在,都有一个你没有努力的曾经。
最新文章
1.
springboot在一個項目中啓動多個核心啓動類
2.
Spring Boot日誌-3 ------>SLF4J與別的框架整合
3.
SpringMVC-Maven(一)
4.
idea全局設置
5.
將word選擇題轉換成Excel
6.
myeclipse工程中library 和 web-inf下lib的區別
7.
Java入門——第一個Hello Word
8.
在chrome安裝vue devtools(以及安裝過程中出現的錯誤)
9.
Jacob線上部署及多項目部署問題處理
10.
1.初識nginx
本站公眾號
歡迎關注本站公眾號,獲取更多信息
相關文章
1.
編程小白必備——主流語言C語言知識點
2.
編程語言常識
3.
C語言一些常識備忘
4.
UDP服務器端程序(C語言)
5.
編程這件小事兒之C語言篇:C語言自學必備
6.
C語言編程練手必備,C 語言快速實現五子棋!
7.
服務器後端的編程語言
8.
維護服務器平常安全有哪些必備常識
9.
在VC6.0下運行C語言程序,以及編程入門必備的常識類小知識!
10.
小螞蟻學習C語言(2)——C語言編程預備知識(上)
>>更多相關文章<<