免費(fèi)可商用素材網(wǎng)站網(wǎng)站百度權(quán)重
一、進(jìn)程的創(chuàng)建和回收
一、進(jìn)程的概念
1、進(jìn)程!=程序
程序是靜態(tài)的,而進(jìn)程是動(dòng)態(tài)的?
2、進(jìn)程和程序的區(qū)別
1)進(jìn)程控制塊中包含進(jìn)程的屬性
2)程序在磁盤里面,堆棧都是在內(nèi)存中,程序運(yùn)行起來都在內(nèi)存中
3)進(jìn)程的運(yùn)行在內(nèi)存(RAM)中,手機(jī)內(nèi)存指的是運(yùn)行內(nèi)存64G,電腦內(nèi)存指的是硬盤(ROM)
4)初始化的全局變量在數(shù)據(jù)段,沒有初始化的全局變量放在BSS中
代碼段存放可執(zhí)行文件,機(jī)器碼
5) static聲明的變量不在棧中,和全局變量放在一起
棧:參數(shù),返回值,局部變量
堆:malloc
6)一個(gè)進(jìn)程會被分為不同的區(qū)域
7)進(jìn)程控制塊(pcb):
PID、進(jìn)程用戶、進(jìn)程狀態(tài)、優(yōu)先級、文件描述符表
3、進(jìn)程的類型
1)交互最常用,前臺運(yùn)行,在shell下可以控制
2)批處理
3)守護(hù)進(jìn)程,一直在后臺運(yùn)行,不能用shell命令控制
4、進(jìn)程的狀態(tài)
二、進(jìn)程常用的命令
1、查看進(jìn)程信息
1)ps當(dāng)前狀態(tài)下的進(jìn)程
2)ps -e當(dāng)前狀態(tài)下Linux所有的進(jìn)程
3)ps -elf Linux下進(jìn)程的詳細(xì)信息
4)進(jìn)程狀態(tài)
5)進(jìn)程標(biāo)志
6)ps下的目錄含義
PID:進(jìn)程ID
CMD:進(jìn)程的名稱
NI:進(jìn)程優(yōu)先級
PRI:進(jìn)程優(yōu)先級
SZ:占用內(nèi)存
C:占用的CPU利用率
7)ps -elf|grep PID
查看某個(gè)進(jìn)程
2、top實(shí)時(shí)查看進(jìn)程信息
1)翻頁shift+'<'(前翻頁)或'>'(后翻頁)
2)top -p PID查看某個(gè)進(jìn)程
3)ctrl+c退出
3、/proc查看進(jìn)程的某個(gè)目錄
4、nice命令
越nice優(yōu)先級越低
?1)一般nice只能調(diào)高
2)只有root才能設(shè)置為負(fù)值
3)nice打開一個(gè)進(jìn)程,設(shè)置優(yōu)先級
4)renice改變優(yōu)先級
5、
6、前臺和后臺的區(qū)別
1)當(dāng)./test運(yùn)行時(shí):
ctrl+C:結(jié)束前臺運(yùn)行
2)ctrl+Z:此時(shí)程序進(jìn)入停止?fàn)顟B(tài)
3)jobs查看后臺進(jìn)程,這時(shí)進(jìn)程已經(jīng)在后臺
4)bg將掛起的進(jìn)程在后臺運(yùn)行
5)fg+序號
進(jìn)程又重新掛到前臺
7、ctrl+Z:把運(yùn)行的前臺進(jìn)程轉(zhuǎn)為后臺并停止
8、./test &進(jìn)入后臺運(yùn)行?
*三、創(chuàng)建子進(jìn)程
(一)創(chuàng)建子進(jìn)程
1、子進(jìn)程的概念
在Linux下除了0號進(jìn)程,其他的進(jìn)程都是由別人創(chuàng)建的
2、創(chuàng)建子進(jìn)程
讓我們的進(jìn)程創(chuàng)建子進(jìn)程
1)代碼
子進(jìn)程B的代碼和A的代碼相同
但子進(jìn)程B只執(zhí)行程序中fork函數(shù)之后的代碼
2)打印結(jié)果
父進(jìn)程子進(jìn)程分別打印
3)如何讓父子進(jìn)程分別執(zhí)行
(二)父子進(jìn)程
1、子進(jìn)程只執(zhí)行fork之后的代碼
2、父子進(jìn)程執(zhí)行順序是操作系統(tǒng)決定的
?3、父子進(jìn)程的關(guān)系
(三)結(jié)束進(jìn)程
4、若父進(jìn)程先結(jié)束,被init進(jìn)程收養(yǎng),子進(jìn)程變成后臺進(jìn)程
1)分別對父子進(jìn)程加一個(gè)sleep
父子進(jìn)程隨機(jī)
子父進(jìn)程ID
2)kill掉父進(jìn)程
子進(jìn)程的父進(jìn)程變成了2107,也就是init
子進(jìn)程變成后臺進(jìn)程
5、如果子進(jìn)程先結(jié)束,父進(jìn)程沒有來得及回收,子進(jìn)程變成僵尸進(jìn)程
kill掉父進(jìn)程
此時(shí)kill掉父進(jìn)程,子進(jìn)程消失
四、子進(jìn)程進(jìn)階
1、孫進(jìn)程
子進(jìn)程也進(jìn)行了for循環(huán)?
解決辦法:子進(jìn)程執(zhí)行結(jié)束break
五、進(jìn)程的退出
exit會刷新緩沖流-庫函數(shù)-<stdlib.h>
_exit不會刷新緩沖流-系統(tǒng)調(diào)用-<unistd.h>
1、main函數(shù)return會隱式調(diào)用exit
兩個(gè)結(jié)果相同,其他函數(shù)return只是返回上一級
2、exit:
兩個(gè)結(jié)果相同
3、_exit:沒有刷新流緩沖區(qū)
六、進(jìn)程的回收
*(一)wait-回收并查看子進(jìn)程的情況
1、status和結(jié)束返回2的進(jìn)程不同
2、16進(jìn)制打印200不是2
3、用宏來取得進(jìn)程的返回值
4、父進(jìn)程對子進(jìn)程的回收
1)不回收
2)回收
僵尸進(jìn)程:子進(jìn)程結(jié)束,但是沒有被父進(jìn)程回收
*(二)waitpid
1、
2、指定pid
3、WNOHANG不阻塞,直接執(zhí)行,如果當(dāng)前子進(jìn)程還未結(jié)束,則會出錯(cuò)
出錯(cuò):
修正:休眠2秒,等子進(jìn)程結(jié)束
二、exec函數(shù)族
一、exec函數(shù)族的執(zhí)行過程
1、父進(jìn)程的父進(jìn)程是shell
2、函數(shù)族-有很多個(gè)函數(shù)
3、通過調(diào)用exec函數(shù)族執(zhí)行某個(gè)程序
4、調(diào)用exec函數(shù)族進(jìn)程當(dāng)前內(nèi)容被指定的程序替換
5、相當(dāng)于父子進(jìn)程執(zhí)行不同程序
二、execl函數(shù)和execlp函數(shù)
1、execl-需要寫全部路徑
相當(dāng)于命令“l(fā)s -a -l”
2、execlp-不需要寫全部路徑
執(zhí)行效果和execl相同
三、execv函數(shù)和execvp函數(shù)
1、execv-全部路徑-將命令定義成數(shù)組
2、execvp-不需要全部路徑-數(shù)組
四、system函數(shù)
1、system的實(shí)現(xiàn)
五、exec函數(shù)族特點(diǎn)
1、exec函數(shù)族-進(jìn)程當(dāng)前內(nèi)容被指定內(nèi)容替換,exec函數(shù)以后的程序沒有被執(zhí)行
2、第0個(gè)參數(shù)不使用但是要寫
3、父子進(jìn)程執(zhí)行不同程序
三、GDB調(diào)試
一、GDB調(diào)試多進(jìn)程程序
1、想要用GDB調(diào)試,編譯加-g
gcc -g -o 文件名
2、進(jìn)入gdb調(diào)試:gdb 可執(zhí)行文件
3、quit 退出
4、start開始調(diào)試
5、n進(jìn)入下一步
6、默認(rèn)跟蹤父進(jìn)程
1)set follow-
顯示可以跟蹤的進(jìn)程
2)set follow-fork-mode
可以繼續(xù)選擇跟蹤父子進(jìn)程
3)跟蹤孩子
set follow-fork-mode child
4)同時(shí)調(diào)試父子進(jìn)程
調(diào)試子進(jìn)程,同時(shí)可以切換父進(jìn)程
5)切換調(diào)試的進(jìn)程
查看可以運(yùn)行的進(jìn)程
從進(jìn)程5切換到了進(jìn)程1
7、調(diào)試多進(jìn)程
四、守護(hù)進(jìn)程
一、守護(hù)進(jìn)程的概念
1、守護(hù)進(jìn)程是后臺進(jìn)程,始終后臺運(yùn)行
2、守護(hù)進(jìn)程獨(dú)立于終端
3、
1)進(jìn)程組:
2)會話:一個(gè)終端界面可以理解成一個(gè)會話
3)控制終端-就是終端
4、
5、守護(hù)進(jìn)程是孤兒進(jìn)程
6、守護(hù)進(jìn)程的創(chuàng)建
1)創(chuàng)建子進(jìn)程,然后令子進(jìn)程變成孤兒進(jìn)程,被init收養(yǎng),變成后臺進(jìn)程
此時(shí)子進(jìn)程已經(jīng)被init收養(yǎng)
2)創(chuàng)建會話-setsid
稱為新的會話組長
自己當(dāng)家做主人了?
3)改變工作目錄-不被之前的父進(jìn)程目錄局限
4)重設(shè)掩碼-創(chuàng)建文件權(quán)限(不是必須的)
5)關(guān)閉打開的文件描述符?
關(guān)閉文件描述符后,不會在打印到屏幕
守護(hù)進(jìn)程不能在屏幕上打印東西,不能接收鍵盤的輸入
7、nohup ./test.c &:將前臺進(jìn)程轉(zhuǎn)為后臺進(jìn)程
沒有寫守護(hù)進(jìn)程變成后臺的方法
二、守護(hù)進(jìn)程的實(shí)現(xiàn)
五、線程的創(chuàng)建和參數(shù)傳遞
一、線程的基本特點(diǎn)
1、線程共享相同的地址空間
共享全局變量
2、線程是在windows下創(chuàng)建的,被Linux引用,Linux不分線程和進(jìn)程
3、線程的特點(diǎn)
4、線程共享資源
常用:靜態(tài)數(shù)據(jù)、文件描述符、工作目錄
5、? 線程的私有資源
常用:錯(cuò)誤號、堆棧
二、使用pthread庫函數(shù)創(chuàng)建線程
線程不是通過Linux內(nèi)核實(shí)現(xiàn),而是由線程庫來實(shí)現(xiàn)
2、創(chuàng)建線程
三、常見編譯錯(cuò)誤及處理方法
鏈接錯(cuò)誤
四、線程的運(yùn)行特點(diǎn)
1、線程創(chuàng)建需要時(shí)間,如果主進(jìn)程退出,線程不能得到執(zhí)行,馬上退出
主進(jìn)程退出,創(chuàng)建的線程也會退出
2、sleep 1秒,線程創(chuàng)建成功
五、線程id的獲取
1、線程的退出
2、pthread_exit()函數(shù)-常用于清理線程
3、打印tid
1)主函數(shù)中,直接獲取
2)pthread_self()函數(shù)-函數(shù)中獲得自己的id
4、打印pid
**六、線程的參數(shù)傳遞
1、通過地址傳遞參數(shù),注意類型轉(zhuǎn)換
void定義下的arg是任意類型,直接轉(zhuǎn)換成Int類型
2、也可以值傳遞-可能會報(bào)警,需要程序員自己保證數(shù)據(jù)長度正確
3、建立多個(gè)線程
七、段錯(cuò)誤的原因及處理方法
六、線程的回收及內(nèi)存演示
一、pthread_join與pthread_exit
相當(dāng)于進(jìn)程中的wait函數(shù)
1、pthread_join主函數(shù)對線程的回收-阻塞函數(shù),線程沒有回收則等待
2、pthread_exit 線程結(jié)束函數(shù)
二、常見的編譯錯(cuò)誤
三、pthread_join函數(shù)特點(diǎn)
1、一個(gè)缺點(diǎn),如果是單線程回收方便,循環(huán)創(chuàng)建多線程,如果最開始的線程沒有結(jié)束,pthread_join也會阻塞
四、線程分離pthread_detach
1、線程主動(dòng)與主控線程斷開關(guān)系,自己可以回收,不需要pthread_join
2、pthread_detach使用
在主函數(shù)中:
不阻塞
在線程函數(shù)中:
3、線程屬性分離
4、回收線程的三種方式
1)pthread_join(局限)
2)pthread_detach
3)創(chuàng)建線程時(shí)分離屬性
五、線程回收內(nèi)存演示
查看內(nèi)存命令: top -p 進(jìn)程號
線程回收前
等待線程回收后
七、線程的取消和清理
一、pthread_cancel與線程取消點(diǎn)
1、查看線程-L大寫
ps -eLf |grep detach
2、殺掉線程
1)必須有取消點(diǎn)-阻塞
2)gdb命令:bt-打印調(diào)用棧
二、GDB調(diào)試段錯(cuò)誤
三、pthread_testcancel手動(dòng)設(shè)置取消點(diǎn)
1、線程取消需要取消點(diǎn)
2、如果不確定有沒有取消點(diǎn),可以手動(dòng)設(shè)置一個(gè)取消點(diǎn)
四、 pthread_setcancelstate設(shè)置取消屬性
1、取消取消點(diǎn)
2、恢復(fù)其他地方取消點(diǎn)
3、主函數(shù)中的sleep
4、
五、線程清理
1、如果線程申請了一塊內(nèi)存,但線程因?yàn)樽枞蝗∠?#xff0c;則會造成內(nèi)存泄露
2、線程清理是在線程異常退出之后,進(jìn)行清理
3、線程的清理函數(shù)本質(zhì)上是宏定義,必須成對使用
push-pop
4、
return可以結(jié)束線程,但是不能出發(fā)清理函數(shù)
5、可以cancel自己
兩種情況:
1)到取消點(diǎn)取消,取消點(diǎn)之前可以取消
2)立即取消
八、**互斥鎖/讀寫鎖/死鎖
一、互斥鎖的概念和使用
(一)臨界資源
1、臨界資源是只允許一個(gè)資源訪問的任務(wù),互斥資源
2、外設(shè)、磁盤都是臨界資源
3、臨界區(qū)是訪問臨界資源的代碼
(二)互斥機(jī)制
1、動(dòng)態(tài)初始化創(chuàng)建
2、靜態(tài)方式創(chuàng)建
3、鎖的銷毀
4、互斥鎖的使用
5、申請鎖
1)兩個(gè)函數(shù)的區(qū)別
6、釋放鎖
*(三)互斥鎖
1、創(chuàng)建兩個(gè)線程,打印字符到文件中
主函數(shù):
1.txt:兩個(gè)線程隨機(jī)打印,亂序
2、使用靜態(tài)方式定義互斥鎖
1)初始化互斥鎖
2)添加互斥鎖
3)添加了互斥鎖之后的1.txt
4)如果線程執(zhí)行多個(gè)任務(wù),例如多個(gè)文件的寫操作,需要定義多個(gè)互斥鎖
二、讀寫鎖概念和使用
1、讀寫鎖-提高線程的讀寫速度-可同時(shí)讀
2、防止讀的時(shí)候有線程寫入
3、同一時(shí)刻只有一個(gè)線程可以獲得寫鎖,同一時(shí)刻可以有多個(gè)線程獲得讀鎖
4、代碼
1)在主函數(shù)中定義讀寫鎖
2)結(jié)構(gòu)體變量聲明
3)加鎖
4)結(jié)果與互斥鎖相同
結(jié)論:讀寫鎖與互斥鎖結(jié)果相近
5、讀寫鎖-只讀
讀寫鎖比互斥鎖好的地方是,讀寫鎖可以允許寫的時(shí)候讀
三、死鎖的避免
1、死鎖的概念
2、死鎖都是在一把鎖的情況下
3、代碼
1)設(shè)置兩把鎖,兩個(gè)線程同時(shí)調(diào)用兩個(gè)資源
2)解決辦法
延長休眠時(shí)間
1、使用一把鎖,鎖越少越好
2、獲得1,2的先后順序相同
九、條件變量的使用及注意事項(xiàng)










十、線程尺及gdb調(diào)試多線程
一、線程池的概念
1、一般線程創(chuàng)建使用完都會被回收
2、線程的創(chuàng)建和銷毀>線程的執(zhí)行,時(shí)間不劃算
3、線程池的結(jié)構(gòu)
1)任務(wù)隊(duì)列
2)線程池工作線程
二、線程池的實(shí)現(xiàn)
三、線程的GDB調(diào)試
1、主函數(shù)
2、設(shè)置斷點(diǎn) b
3、run運(yùn)行程序
4、info thread查看線程
5、切換線程
6、下一步next
7、執(zhí)行完一個(gè)線程后再次查看,線程消失
8、
9、設(shè)置線程鎖
設(shè)置之后,除了選定的線程,其他不執(zhí)行
10、切換到第3個(gè),第6行斷電
十一、有名管道和無名管道
一、無名管道基礎(chǔ)
(一)進(jìn)程間通信方式
**(面試題)1、進(jìn)程間通信的方式
1)無名管道-親緣進(jìn)程
2)有名管道
*3)信號
4)共享內(nèi)存
5)套接字-網(wǎng)絡(luò)-進(jìn)程間通信
進(jìn)程-進(jìn)程/主機(jī)-主機(jī)
開銷最大
6)古老
(二)無名管道的特點(diǎn)
1、概念
相當(dāng)于共享內(nèi)存,通過管道傳遞消息
2、特點(diǎn)
1)只能父子或兄弟
2)單工通訊-固定讀端和寫端
2)創(chuàng)建兩個(gè)文件描述符
3、無名管道的創(chuàng)建
單工通信-每個(gè)進(jìn)程fd[0]和fd[1]只能用一個(gè)
(三)無名管道的創(chuàng)建
父子進(jìn)程間的通信:
只有讀操作之后才能打印buf
二、無名管道進(jìn)階
1、父進(jìn)程創(chuàng)建了無名管道
2、子進(jìn)程進(jìn)程描述符相同
3、關(guān)閉管道
父子進(jìn)程都可以關(guān)閉讀寫管道,無論這一段是讀還是寫
4、在同一個(gè)進(jìn)程自己讀和自己寫是進(jìn)行不了的
子進(jìn)程之間相互通信:
5、管道可以用于大于兩個(gè)進(jìn)程的共享
6、可以兩個(gè)子進(jìn)程讀/寫,父進(jìn)程寫/讀
7、無名管道的讀寫特性
管道大小是64K
三、有名管道概念和使用
(一)有名管道的特點(diǎn)
1、通過文件系統(tǒng),但是文件不是放在磁盤,放在內(nèi)存中,通過文件IO
2、有名管道的特點(diǎn)
(二)有名管道的創(chuàng)建
1、有名管道的創(chuàng)建
路徑不能是Linux和wins共享目錄
2、直接創(chuàng)建在根目錄下
(三)有名管道的讀寫
1、寫進(jìn)程代碼:
2、讀進(jìn)程代碼:
讀寫結(jié)果:
四、有名管道的注意事項(xiàng)
1、不能使用讀寫方式打開文件
2、文件可以創(chuàng)建在根目錄下,但是不能創(chuàng)建在共享目錄下
3、默認(rèn)情況下只寫O_RDWR和只讀O_RDONLY參數(shù)是阻塞的,加了第二個(gè)參數(shù),不會阻塞,沒有內(nèi)容可讀,直接退出
一個(gè)參數(shù)阻塞:
兩個(gè)參數(shù):
讀文件:沒有內(nèi)容直接報(bào)錯(cuò)
有內(nèi)容讀內(nèi)容
寫文件:打開失敗