linux编程基础_第1篇 Linux系统编程 -多线程基础
進程
在理解線程之前,首先需要了解UNIX/Linux進程。 進程是由操作系統(tǒng)創(chuàng)建的,需要相當(dāng)數(shù)量的“開銷”。 進程包含有關(guān)程序資源和程序執(zhí)行狀態(tài)的信息,包括:它是一個在隨機訪問內(nèi)存(RAM)中,正在執(zhí)行的程序,它是資源分配的最小單位。
- 1)進程ID,進程組ID,用戶ID和組ID
- 2)環(huán)境
- 3)工作目錄
- 4)程序說明
- 5)寄存器
- 6)棧
- 7)堆
- 8)文件描述符
- 9)信號動作
- 10)共享庫
- 11)進程間通信工具(例如消息隊列,管道,信號量或共享內(nèi)存)
線程
它是程序執(zhí)行的最小單位,又稱為輕量級的進程,操作系統(tǒng)獨立調(diào)度和分派到CPU的基本單位,它是進程中的一個實體,一個進程中可以包含多個線程。這些線程共享同一個進程中的資源,我們之前以進程為單位的編程模式,也叫單線程的編程模式
- 存在于進程中并使用進程資源
- 只要其父進程存在并且操作系統(tǒng)支持它,便擁有自己的獨立控制流
- 僅復(fù)制需要獨立計劃的必要資源
- 可以與相對地"平等"運行的其他線程共享進程資源
- 如果父進程死亡-所有線程就不復(fù)存在
- 是“輕量級的”,因為大多數(shù)開銷已經(jīng)通過創(chuàng)建其進程來完成。
并發(fā):在同一個核心的CPU中,同一個時刻,只能有一條指令執(zhí)行,但多個進程指令被快速輪換執(zhí)行,使得在宏觀上具有多個進程同時執(zhí)行的效果。
并行:是指在同一個時刻,有多條指令在多個處理器上同時執(zhí)行。
同步:彼此有依賴關(guān)系的調(diào)用不應(yīng)“同時發(fā)生”,而同步就是阻止同時發(fā)生的事情,同步機制通常是一個線程擁有可以訪問系統(tǒng)資源的鎖,意味著某個線程在某一時刻執(zhí)行時占用著CPU資源和進程級別的共享對象會被"鎖定",其他線程會被抑制執(zhí)行而無法獲取CPU資源和進程級別共享對象訪問的控制權(quán),只有等到擁有該鎖的線程的鎖釋放后,其他線程有機會"爭奪"獲得該鎖才能獲得CPU資源和進程的共享對象訪問的控制權(quán)。
異步:和同步的概念是相對的,任何兩個彼此獨立的操作是異步的,它表明事件是獨立發(fā)生的。
題外話
還記得我經(jīng)常說CPython更新到3.9版本為止,實質(zhì)上仍然是一個單線程的語言,它壓根就不存在線程并發(fā),任何說CPython是一個線程并發(fā)的話語都是自欺欺人的。就因為全局解釋器鎖(GIL),因為CPython的內(nèi)存垃圾回收機制中,所有PyObject對象內(nèi)部都有一個引用計數(shù)器,在不存在GIL的多線程運行情況下,運行中的相關(guān)PyObject對象的引用計數(shù)器的值存在被某一個或多個線程篡改,從而導(dǎo)致內(nèi)存回收機制無法正常執(zhí)行的風(fēng)險,因此CPython只能通過GIL來束縛某個時刻多個獨立線程運行的情況出現(xiàn)。次要原因要追溯CPython內(nèi)存垃圾回收的單一化實現(xiàn),而從目前CPython的源代碼看來,除了將基礎(chǔ)的內(nèi)核代碼推倒重來并加入更多的內(nèi)存垃圾回收的算法現(xiàn)實,不然未來不太可能移除GIL。因此為了擺脫GIL,后來陸續(xù)出現(xiàn)了PyPy、Cython、Jython、Number和IronPython這些不同的實現(xiàn)。
創(chuàng)建一個線程
首先每個線程,操作系統(tǒng)都會給每個線程分配一個線程ID,在Linux下,進程ID是一個pid_t類型的整數(shù),線程ID是一個標(biāo)識符類型pthread_t的整數(shù)
像pthread_self()和getpid()這些函數(shù)在安裝Linux/Unix系統(tǒng)后原生內(nèi)置的函數(shù),通常叫系統(tǒng)調(diào)用(Syscall),就是系統(tǒng)原生提供給C/C++程序員使用的系統(tǒng)函數(shù)接口,這些系統(tǒng)函數(shù)通常可以通過man命令能夠查到它的使用方法,例如可以在/usr/include目錄下查看對應(yīng)的系統(tǒng)函數(shù)的頭文件
vim /usr/include/bits/pthreadtypes.h我們知道,線程ID其實就是一個long int的無符號整數(shù)
我們也可以通過man getpid和man pthread_self分別查看一下,在使用它們之前需要導(dǎo)入那些依賴的頭文件,如果你不熟悉的系統(tǒng)函數(shù),你應(yīng)該經(jīng)常通過man指令來查看對應(yīng)的描述文檔。
編程示例
我們在沒有提及多線程編程模式的時,那些編寫的示例代碼都是單線程的程序,也就是一個進程中只有一個線程。我們下面的例子是要獲取當(dāng)前運行進程的ID和線程ID,該示例就是一個單線程的程序。
#include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <stdlib.h> #include <pthread.h>int main(void){pid_t pid=getpid();pthread_t tid=pthread_self();printf("當(dāng)前線程ID:%lx,進程ID:%un",tid,pid);return 0; }在編譯多線程的程序時,記得鏈接pthread庫,即
gcc app.c -o app -pthread輸出
當(dāng)前線程ID:7fedbcb524c0,進程ID:30167小結(jié):
進程是獲取資源的最小單位,例如組成我們進程的函數(shù)棧和堆內(nèi)存,注意在主流系統(tǒng)中每個進程中有它對應(yīng)的函數(shù)棧和堆內(nèi)存,而且這些堆和棧對用于它們的進程來說是私有的,其他進程無法訪問。
線程是進程中的一個或多個實例,而線程的職責(zé)是消耗進程獲得的系統(tǒng)資源(CPU中的寄存器,計算單元和控制單元,以及隨機訪問內(nèi)存),在一個進程中,只有一個線程的程序,該線程也叫主線程,主線程可以創(chuàng)建其他子線程
總結(jié)
以上是生活随笔為你收集整理的linux编程基础_第1篇 Linux系统编程 -多线程基础的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: asp连接mysql oledb_ASP
- 下一篇: 请求成功得到返回数据还是走到catch_