系統(tǒng)編程

引出系統(tǒng)編程

=============

? ? 1.實際開發(fā)中:需要多個程序能夠"同時"運行(一心多用)

? ? ? 系統(tǒng)編程:解決多任務(wù)的并發(fā)操作

? ? ? ? ? ? ? ? 不同程序之間的通信(收發(fā)數(shù)據(jù))

? ? ? ? ? ? ? ? 多個程序同時去訪問一個共享資源(比如說火車票總數(shù)),需要協(xié)調(diào)一下


? ? ? int main()

? ? ? {

? ? ? ? ? ? show_pic();

? ? ? ? ? ? show_login();

? ? ? ? ? ? //先后依次執(zhí)行,前面的不執(zhí)行完畢,后面的是沒有機會

? ? ? ? ? ? //學習了系統(tǒng)編程的技術(shù),解決多個任務(wù)同時執(zhí)行的問題

? ? ? }

系統(tǒng)編程主要知識點

===================

? ? ? 1.多進程

? ? ? ? ? ? 進程相關(guān)理論概念

? ? ? ? ? ? 進程創(chuàng)建,回收,退出....的相關(guān)接口函數(shù)

? ? ? ? ? ? 進程間常用的通信方式

? ? ? 2.多線程

? ? ? ? ? ? 線程相關(guān)理論概念

? ? ? ? ? ? 線程創(chuàng)建,回收,退出,設(shè)置屬性....的相關(guān)接口函數(shù)

? ? ? ? ? ? 線程的同步與互斥

? ? ? ? ? ? 線程池

多進程(創(chuàng)建多個進程,幫助我實現(xiàn)多個任務(wù)的并發(fā)操作)

==============

? ? ? 1.進程有關(guān)的理論概念:

? ? ? ? ? ? 進程:動態(tài)的概念,需要程序運行起來才會有進程,不運行程序,是不會有對應(yīng)的進程產(chǎn)生,一個正在運行的程序就是一個進程

? ? ? ? ? ? 程序:靜態(tài)的概念,指的是你用編譯器編譯好的二進制文件,存放在磁盤的

? ? ? ? ? ? 命令:ps? -elf? 查看當前系統(tǒng)中進程的信息

? ? ? ? ? ? ? ? ? ? 其中PID(當前進程的id號)? CMD(當前進程的名字)

? ? ? ? ? ? 父進程:程序中調(diào)用了fork,那么該程序被稱作父進程,fork創(chuàng)建出來的新的進程稱作子進程

? ? ? ? ? ? 子進程:

? ? ? ? ? ? 孤兒進程(僵尸進程,僵死進程):父進程優(yōu)先于子進程退出,導致子進程沒有人理會它(孤兒),系統(tǒng)中會有一個init的進程專門負責回收孤兒

? ? ? ? ? ? 進程的組成:數(shù)據(jù)段,代碼段,進程控制塊(PCB)

? ? ? ? ? ? ? ? ? ? 進程控制塊:指的就是struct task_struct

? ? ? ? ? ? ? ? ? ? struct task_struct用來存放跟進程有關(guān)的信息

? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? ? pid_t pid;

? ? ? ? ? ? ? ? ? ? ? ? ? unsigned int policy; cpu調(diào)度策略

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? linux用宏定義定義了幾個宏,每個宏表示不同的調(diào)度策略

? ? ? ? ? ? ? ? ? ? ? ? ? *files; //指向存放文件信息數(shù)組的一個指針

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? /usr/src/linux-headers-3.5.0-23-generic/include/linux/sched.h 1229行

? ? ? ? ? ? 進程組:多個進程的集合,對比用戶組


? ? ? 2.進程創(chuàng)建的相關(guān)接口函數(shù)

? ? ? ? ? ? (1)進程的創(chuàng)建

? ? ? ? ? ? ? ? ? pid_t fork(void);

? ? ? ? ? ? ? ? ? ? ? 返回值:(重點,難點)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? >0? 表示子進程的id號,父進程

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ==0 表示子進程

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <0? 失敗

? ? ? ? ? ? ? ? ? ? ? 注意:常規(guī)的函數(shù),返回值只能是多種情況中的一種

? ? ? ? ? ? ? ? ? ? ? ? ? ? fork很特殊,一次調(diào)用,兩次返回(兩次返回的目的在于,fork源碼內(nèi)部幫助你為子進程申請了獨立的空間幫助子進程運行,返回兩個結(jié)果區(qū)分誰是父進程,誰是子進程)

? ? ? ? ? (2)進程的退出跟回收

? ? ? ? ? ? ? ? void exit(int status);? //return -1? return 0

? ? ? ? ? ? ? ? ? ? ? 參數(shù):進程退出時候的狀態(tài)值? 強行退出進程

? ? ? ? ? ? ? ? ? ? ? ? exit(1); //結(jié)束整個進程

? ? ? ? ? ? ? ? return 1; //僅僅只是函數(shù)返回一個結(jié)果給調(diào)用者

? ? ? ? ? ? ? ? void _exit(int status);

? ? ? ? ? ? ? ? ? ? ? 區(qū)別:exit結(jié)束進程的時候幫助你刷新緩沖區(qū)

? ? ? ? ? ? ? ? ? ? ? ? ? ? _exit結(jié)束進程的時候不刷新緩沖區(qū)

? ? ? ? ? ? ? ? #include <sys/wait.h>?

? ? ? ? ? ? ? ? ? ? pid_t wait(int *stat_loc);

? ? ? ? ? ? ? ? ? ? ? ? ? ? 返回值:成功 返回回收到子進程的id號

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 失敗 -1

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 參數(shù):(重點)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 存放進程退出時的狀態(tài)信息(exit退出值僅僅只是退出狀態(tài)信息的一部分)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 需要通過系統(tǒng)提供的宏函數(shù)幫助你分析退出原因,退出值等等

? ? ? ? ? ? ? ? ? ? pid_t waitpid(pid_t pid, int *stat_loc, int options);

? ? ? ? ? ? ? ? ? ? ? ? ? ? 返回值:成功 返回回收到子進程的id號

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 失敗 -1

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 參數(shù):pid --》

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? < -1? 例如:waitpid(-2156,status,options)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 回收進程組id是2156這個組里面的某個子進程

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -1? ? 例如:waitpid(-1,status,options)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 回收任意一個子進程

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0? ? 例如:waitpid(0,status,options)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 回收本進程組里面的任意一個子進程? ?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? >0(重點) 例如:waitpid(1234,status,options)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 指定回收id是1234的那個子進程

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? options --》WNOHANG? 非阻塞等待回收(等的了就等,等不了就直接退出)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0? ? ? ? 阻塞等待回收


? ? ? ? ? (3)打印當前進程的id,已經(jīng)父進程的id號

? ? ? ? ? ? ? ? pid_t getpid(void);

? ? ? ? ? ? ? ? pid_t getppid(void);

? ? ? ? ? ? ? ? gid_t getgid(void); //獲取進程組id

? ? ? ? ? (4)進程中調(diào)用執(zhí)行其他的進程

? ? ? ? ? ? ? ? 方法一:system() //執(zhí)行shell命令或者程序

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? system("ls -l")

? ? ? ? ? ? ? ? 方法二:exec函數(shù)族

? ? ? ? ? ? ? ? ? ? ? 總結(jié):函數(shù)名字中帶有l(wèi)(list),表示參數(shù)以列表的形式列舉

? ? ? ? ? ? ? ? ? ? ? ? ? ? 函數(shù)名字中帶有p,去環(huán)境變量中找命令,程序

? ? ? ? ? ? ? ? ? ? ? ? ? ? 函數(shù)名字中帶有e,可以設(shè)置環(huán)境變量(實際操作發(fā)現(xiàn)設(shè)置不了)

? ? ? ? ? ? ? ? ? ? ? ? ? ? 函數(shù)名字中帶有v,參數(shù)采用指針數(shù)組傳遞(對比l)?

? ? ? ? ? ? ? ? ? ? ? int execl(const char *path, const char *arg, ...);

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 參數(shù):path --》你要執(zhí)行的那個進程,命令的路徑名

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? arg --》你要執(zhí)行的程序,命令參數(shù),參數(shù)要求以列表的形式列舉出來


? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 例如:執(zhí)行l(wèi)s? -l?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? execl("/bin/ls","ls","-l",NULL);


? ? ? ? ? ? ? ? ? ? ? int execlp(const char *file, const char *argument, ...);

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? execlp("cp","cp","1.txt","/home/gec",NULL)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? execlp("11","./11",NULL); //11程序必須存放在環(huán)境變量/bin中

? ? ? ? ? ? ? ? ? ? ? int execle(const char *path, const char *arg,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ..., char * const envp[]);

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 例如:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? char *envp[]={"PATH=/mnt/hgfs/share",NULL};

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? execle("/bin/ls","ls","-l",NULL,envp);

? ? ? ? ? ? ? ? ? ? ? int execv(const char *path, char *const argv[]);

? ? ? ? ? ? ? ? ? ? ? int execvp(const char *file, char *const argv[]);

? ? ? ? ? ? ? ? ? ? ? int execvpe(const char *file, char *const argv[],

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? char *const envp[]);


進程間的通信

================

? ? 1.解決的問題:進程之間雖然各自有自己的獨立空間,但是需要數(shù)據(jù)的交互

? ? 2.通信方式:

? ? ? ? ? ? 管道:無名管道,有名管道

? ? ? ? ? ? SYSTEM-V ipc通信:共享內(nèi)存,消息隊列,信號量

? ? ? ? ? ? 信號:

? ? 3.管道

? ? ? ? ? ? 無名管道

? ? ? ? ? ? ? (1)相關(guān)的接口函數(shù)

? ? ? ? ? ? ? ? ? ? 無名管道的創(chuàng)建

? ? ? ? ? ? ? ? ? ? ? int pipe(int fildes[2]);

? ? ? ? ? ? ? ? ? ? ? ? ? 返回值:成功 0? 失敗 -1

? ? ? ? ? ? ? ? ? ? ? ? ? ? 參數(shù):fildes[0]? 讀端的文件描述符

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? fildes[1]? 寫端的文件描述符

? ? ? ? ? ? ? 總結(jié):如果管道里面沒有內(nèi)容,讀的時候會阻塞

? ? ? ? ? ? ? ? ? ? 只能用于用血緣關(guān)系的進程之間(父子進程,兄弟進程)

? ? ? ? ? ? ? ? ? ? 無名管道沒有對應(yīng)的管道文件


? ? ? ? ? ? 有名管道

? ? ? ? ? ? ? (1)相關(guān)的接口函數(shù)

? ? ? ? ? ? ? ? ? ? ? 有名管道的創(chuàng)建

? ? ? ? ? ? ? ? ? ? ? int mkfifo(const char *pathname, mode_t mode);

? ? ? ? ? ? ? ? ? ? ? ? ? ? 返回值:成功 0? 失敗 -1

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 參數(shù):pathname --》你要創(chuàng)建的有名管道的路徑名

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? mode --》權(quán)限 0777? 0666

? ? ? ? ? ? ? 總結(jié):不能在共享里面創(chuàng)建有名管道,原因是windows不支持這種格式的文件

? ? ? ? ? ? ? ? ? ? 可以用于沒有血緣關(guān)系的進程之間通信

? ? ? ? ? ? ? ? ? ? 不區(qū)分讀端寫端

? ? ? ? ? ? ? ? ? ? 有對應(yīng)的管道文件

? ? 4.信號

? ? ? ? ? 討論的核心問題:給進程發(fā)送信號之后,進程做何反應(yīng)

? ? ? ? ? 生活中的例子類比:

? ? ? ? ? ? ? 紅綠燈:? 紅燈 --》法律規(guī)定的默認動作,停下來

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 怕什么,闖紅燈

? ? ? ? ? 相關(guān)的linux命令:

? ? ? ? ? ? ? ? kill? -STOP? 進程的id號

? ? ? ? ? ? ? ? kill? -19? 進程的id號

? ? ? ? ? ? ? ? killall -STOP? 進程的名字

? ? ? ? ? ? ? ? killall -19? 進程的名字

1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP

6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1

11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM

16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP

21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ

26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR

31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3

38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8

43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13

48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12

53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7

58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2

63) SIGRTMAX-1 64) SIGRTMAX

? ? ? ? ? ? (1)相關(guān)的接口函數(shù)

? ? ? ? ? ? ? ? ? #include <signal.h>

? ? ? ? ? ? ? ? ? int kill(pid_t pid, int sig);

? ? ? ? ? ? ? ? ? ? ? ? ? 返回值:成功 0? 失敗 -1

? ? ? ? ? ? ? ? ? ? ? ? ? ? 參數(shù):pid --》進程的id

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sig --》你要發(fā)送的信號

? ? ? ? ? (2)捕捉信號并改變信號的響應(yīng)動作

? ? ? ? ? ? ? ? ? 正常情況下:發(fā)送信號給進程,絕大部分信號都會終止進程

? ? ? ? ? ? ? ? ? 實際需求:我想自主改變信號的響應(yīng)動作

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 比如:SIGINT --》正常動作,終止進程

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 修改成,跳個舞

? ? ? ? ? ? ? ? void (*signal(int sig,void(*func)(int)))(int);

? ? ? ? ? ? ? ? ? ? ? ? ? 返回值:

? ? ? ? ? ? ? ? ? ? ? ? ? ? 參數(shù):sig --》你想要捕捉的信號的序號

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? void(*func)(int) --》函數(shù)指針

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? void tiaowu(int sig)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? printf("跳舞咯!\n");

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? signal(SIGINT,tiaowu);

? ? ? ? ? (3)阻塞進程等待信號到來

? ? ? ? ? ? ? ? int pause(void);? ? ? ? ? ? ? ?

(4)另外一組信號的發(fā)送和捕捉函數(shù)

? ? ? ? ? ? 第一組:kill()和signal()

? ? ? ? ? ? 第二組:sigqueue()和sigaction()

? ? ? ? ? int sigqueue(pid_t pid, int sig,const union sigval value); //買一送一,發(fā)送信號的同時攜帶額外數(shù)據(jù)

? ? ? ? ? ? ? ? ? ? ? ? ? 返回值:

? ? ? ? ? ? ? ? ? ? ? ? ? ? 參數(shù):value --》 union sigval {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int? sival_int; //存放你要發(fā)送的某個整數(shù)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? void *sival_ptr; //存放你要發(fā)送的某個指針

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? };

? ? ? ? int sigaction(int sig, const struct sigaction * act,struct sigaction *oact);

? ? ? ? ? ? ? ? ? ? ? ? 返回值:

? ? ? ? ? ? ? ? ? ? ? ? ? 參數(shù):struct sigaction結(jié)構(gòu)體成員如下:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? void(*) (int)? sa_handler? ? 跟signal的函數(shù)指針一模一樣?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sigset_t? ? ? ? sa_mask? ? ? ? 信號阻塞掩碼

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int? ? ? ? ? ? sa_flags? ? ? 選擇 SA_SIGINFO表示使用sa_sigaction

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 選擇 0表示使用sa_handler? ? ?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? void(*)(int, siginfo_t *,void *) sa_sigaction 為了配合sigqueue攜帶額外數(shù)據(jù)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? siginfo_t

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int si_int;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? void *si_ptr;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }

? ? (5)信號的阻塞(屏蔽)

? ? ? ? ? 信號的阻塞:進程將信號掛起(把信號擋在外面),暫時不去響應(yīng),一旦解除阻塞,立馬響應(yīng)

? ? ? ? ? 信號的忽略:signal(? SIG_IGN) 進程舍棄掉接收的信號,不去響應(yīng)

? ? ? ? ? 設(shè)置信號阻塞的函數(shù)?

? ? ? ? ? int sigprocmask(int how, const sigset_t *restrict set,sigset_t *restrict oset)

? ? ? ? ? ? ? ? ? ? sigset_t:作用是專門存放你想要阻塞的那些信號

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 稱作為信號阻塞掩碼集

? ? ? ? ? ? ? ? ? ? 返回值:

? ? ? ? ? ? ? ? ? ? ? 參數(shù):how --》SIG_BLOCK? //設(shè)置信號阻塞,將set中信號添加到原本oset中

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? SIG_SETMASK //設(shè)置信號阻塞,用set中的信號替換掉(覆蓋掉)原本oset中

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? SIG_UNBLOCK ////設(shè)置信號解除阻塞

? ? ? ? ? ? ? ? ? ? ? ? ? set --》新設(shè)置的阻塞掩碼集

? ? ? ? ? ? ? ? ? ? ? ? ? oset --》保存原本的阻塞掩碼集,不想保存,就設(shè)置為NULL

? ? ? ? 操作信號阻塞掩碼集

? ? ? ? ? ? int sigemptyset(sigset_t *set); //清空集合

? ? ? ? ? ? int sigfillset(sigset_t *set); //一口氣將linux中所有的信號全部加入集合

? ? ? ? ? ? int sigaddset(sigset_t *set, int signum);

? ? ? ? ? ? int sigdelset(sigset_t *set, int signum);

? ? ? ? ? ? int sigismember(const sigset_t *set, int signum); //判斷signum在不在集合中

? ? ? ? ? ? ? ? ? ? ? ? ? 返回值:1表示是成員? 0表示不是成員? -1失敗


? ? ? ? 使用思路:

? ? ? ? ? ? ? 步驟一:想清楚你要阻塞那些信號

? ? ? ? ? ? ? 步驟二:定義集合變量,并將這些信號添加到集合中

? ? ? ? ? ? ? 步驟三:調(diào)用sigprocmask讓阻塞生效

system-v ipc通信:共享內(nèi)存,消息隊列,信號量

==================

? ? ? 命令:查看共享內(nèi)存

? ? ? ? ? ? ? ipcs -m

? ? ? ? ? ? 刪除共享內(nèi)存

? ? ? ? ? ? ? ipcrm -m? 共享內(nèi)存的id號

? ? ? (1)共享內(nèi)存

? ? ? ? ? ? 第一個函數(shù):申請共享內(nèi)存

? ? ? ? ? ? ? ? ? #include <sys/shm.h>

? ? ? ? ? ? ? ? ? ? int shmget(key_t key, size_t size, int shmflg);

? ? ? ? ? ? ? ? ? ? ? ? ? ? 返回值:成功返回共享內(nèi)存的id? 失敗 -1

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 參數(shù):key(重點):鍵值,本質(zhì)就是個整數(shù),確保申請的內(nèi)存唯一性,大家都一樣

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 寫法有兩種:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 第一種:程序員自己隨便寫個正整數(shù)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 第二種:使用linux提供的ftok()生成鍵值

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #include <sys/types.h>

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #include <sys/ipc.h>

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? key_t ftok(char *pathname,int proj_id);

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 返回值:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 參數(shù):pathname--》任意合法有效的路徑

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? proj_id--》任意一個整數(shù)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ftok("/home/gec",15);

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ftok("/home/gec",10);

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? size:你打算申請多大的內(nèi)存,1024的整數(shù)倍

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? shmflg: IPC_CREAT

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? IPC_EXCL

? ? ? ? ? ? 第二個函數(shù):映射共享內(nèi)存(得到共享內(nèi)存的首地址)?

? ? ? ? ? ? ? ? ? ? ? void *shmat(int shmid, const void *shmaddr, int shmflg);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 返回值:你剛才申請的共享內(nèi)存的首地址

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 失敗? NULL

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 參數(shù):shmid--》共享內(nèi)存id? ? ? ? ? ? ? ? ? ?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? shmaddr --》一般設(shè)置為NULL,表示系統(tǒng)自動分配

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? shmflg --》一般設(shè)置為0 表示共享內(nèi)存可讀可寫

? ? ? ? ? ? 第三個函數(shù):解除映射

? ? ? ? ? ? ? ? ? ? int shmdt(const void *shmaddr);

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 返回值:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 參數(shù):shmaddr --》共享內(nèi)存的首地址

? ? ? ? ? ? 第四個函數(shù):多功能函數(shù),刪除共享內(nèi)存,獲取,設(shè)置共享內(nèi)存的屬性信息

? ? ? ? ? ? ? ? ? ? int shmctl(int shmid, int cmd, struct shmid_ds *buf);

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 參數(shù):cmd --》IPC_STAT 獲取共享內(nèi)存的屬性信息

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? IPC_SET? 設(shè)置共享內(nèi)存的屬性信息

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? IPC_RMID 刪除,刪除的時候需要用到最后一個參數(shù)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? buf --》 struct shmid_ds 存放你獲取,設(shè)置的屬性信息

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? shm_segsz; //存放大小的

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }


信號量

====================

? ? ? ? ? ipcs -s 查看信號量

? ? ? ? ? ipcrm? -s? 信號量的id? ? 刪除信號量

? ? ? ? ? 相關(guān)的接口函數(shù):

? ? ? ? ? ? ? 第一個函數(shù):創(chuàng)建信號量(申請積分卡)

? ? ? ? ? ? ? ? ? ? ? #include <sys/sem.h>

? ? ? ? ? ? ? ? ? ? ? ? int semget(key_t key, int nsems, int semflg);

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 參數(shù):nsems --》你打算申請多少個信號量

? ? ? ? ? ? ? 第二個函數(shù):設(shè)置信號量的初始值

? ? ? ? ? ? ? ? ? ? ? int semctl(int semid, int semnum, int cmd, ...);

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 參數(shù):semnum(重點) --》信號量的序號,從0開始,第一個信號量序號是0

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 例如:semget(7884,2,IPC_CREAT|IPC_EXCL|0777);

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? semctl(id,0,SETVAL,1); 將第一個信號量(序號是0)值設(shè)置為1

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? semctl(id,1,SETVAL,0); 將第二個信號量(序號是1)值設(shè)置為0

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int num=semctl(id,0,GETVAL); 獲取第一個信號量的值返回保存到num

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? cmd --》GETVAL? 獲取當前信號量值(積分值)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? SETVAL? 設(shè)置當前信號量值

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? IPC_RMID 刪除

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct? semid_ds? mysemds;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? semctl(semid,0,IPC_STAT,&mysemds);? //獲取屬性

? ? ? ? ? ? ? 第三個函數(shù):使用信號量(*****重點)

? ? ? ? ? ? ? ? ? ? int semop(int semid, struct sembuf *sops, size_t nsops);

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 參數(shù):struct sembuf *sops

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? short sem_num? 信號量的序號,從0開始

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? short sem_op? pv操作? 寫負數(shù)就表示減法(p操作)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 寫正數(shù)就表示加法(v操作)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? short sem_flg? 設(shè)置為SEM_UNDO宏定義,使用完信號量以后,不刪除的情況,程序退出,值恢復成原來的值

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? nsops --》struct sembuf 結(jié)構(gòu)體的個數(shù),一般寫成1

? ? ? ? ? ? 總結(jié):信號量的特點

? ? ? ? ? ? ? ? ? ? 信號量的值是絕對不會出現(xiàn)負數(shù)

? ? ? ? ? ? ? ? ? ? 信號量的值如果是0,你還要進行p操作(減法操作),會導致當前進程阻塞(重點)

? ? ? ? ? ? ? ? ? ? ? ? ? ? 只有阻塞了其他進程,我這個進程不就有機會了嗎(阻塞別人,成全自己)

? ? ? ? ? ? ? ? ? ? 信號量進行v操作是絕對不會阻塞

進程的生老病死(純理論)

==============

? ? 進程有如下幾種狀態(tài):

? ? ? ? ? 就緒態(tài):進程已經(jīng)準備好要執(zhí)行了,但是還沒有獲得cpu的使用權(quán)

? ? ? ? ? 執(zhí)行態(tài):進程獲得了cpu的使用權(quán),開始執(zhí)行了

? ? ? ? ? 睡眠態(tài)、掛起態(tài):使用sleep()函數(shù)

? ? ? ? ? 暫停態(tài):進程收到STOP信號

? ? ? ? ? 僵尸態(tài):進程退出了,但是沒有人回收

? ? ? ? ? 死亡態(tài):進程退出了,有人回收wait() waitpid()

多線程

===========

? ? (1)相關(guān)的理論概念:

? ? ? ? ? ? 線程是"輕量級"的"進程"

? ? ? ? ? ? 線程依賴于進程存在,它的資源都是進程給的

? ? ? ? 孤兒線程:線程退出的時候,主線程沒有去回收它

? ? (2)相關(guān)的接口函數(shù)

? ? ? ? ? 第一個函數(shù):線程的創(chuàng)建

? ? ? ? ? ? ? #include <pthread.h>

? ? ? ? ? ? ? int pthread_create(pthread_t *thread, const pthread_attr_t *attr,

? ? ? ? ? ? ? ? ? ? ? ? ? void *(*start_routine) (void *), void *arg);

? ? ? ? ? ? ? ? ? ? 返回值:成功0? 失敗 錯誤碼

? ? ? ? ? ? ? ? ? ? ? 參數(shù):thread --》存放線程的id

? ? ? ? ? ? ? ? ? ? ? ? ? ? attr --》存放線程的屬性(后面會專題討論),目前設(shè)置為NULL,表示使用默認屬性

? ? ? ? ? ? ? ? ? ? ? ? ? ? void *(*start_routine)(void *) --》你創(chuàng)建線程需要執(zhí)行的任務(wù),就通過該指針指向的函數(shù)去實現(xiàn)?

? ? ? ? ? ? ? ? ? ? ? ? ? ? arg --》傳遞給start_routine的參數(shù)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 由于類型是void *,表示可以接收任何類型的指針

? ? ? ? ? ? ? ? ? Compile and link with -pthread.? //編譯的時候必須加上線程庫

? ? ? ? ? ? ? ? ? ? ? gcc thread.c -o thread? -pthread

? ? ? ? ? ? ? ? ? ? ? gcc thread.c -o thread? -lpthread? 都對


? ? ? ? ? 第二個函數(shù):線程的退出和回收

? ? ? ? ? ? ? ? ? void pthread_exit(void *retval); //退出?

? ? ? ? ? ? ? ? ? ? ? ? ? 參數(shù):retval --》存放線程退出時候的信息

? ? ? ? ? ? ? ? ? int pthread_join(pthread_t thread, void **retval); //回收線程

? ? ? ? ? ? ? ? ? ? ? ? ? 參數(shù):thread --》線程的id

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? retval --》二級指針,存放線程退出信息的(pthread_exit里面參數(shù)的內(nèi)容)

? ? ? ? ? ? ? ? ? 總結(jié):遇到二級指針,復雜--》簡化(定義一個一級指針輔助你理解)

? ? ? ? ? 第三個函數(shù):獲取當前線程的id

? ? ? ? ? ? ? ? ? pthread_t pthread_self(void);

后續(xù)課程

===========

? 網(wǎng)絡(luò)編程

? shell編程 --》學習過linux中常用shell命令

? ? ? ? ? ? ? ? 用shell編程的語法規(guī)則將前面學習的這些命令寫個一個腳本

? 音視頻

? 串口編程

? C++和QT

線程的屬性設(shè)置

================

? ? ? (1)線程屬性很多,教大家一般方法

? ? ? ? 在linux中定義了一個結(jié)構(gòu)體存放線程的所有屬性,類型叫做pthread_attr_t


? ? ? ? ? 步驟:

? ? ? ? ? ? ? ? 第一步:定義線程屬性變量并初始化

? ? ? ? ? ? ? ? ? ? ? ? int pthread_attr_init(pthread_attr_t *attr);

? ? ? ? ? ? ? ? 第二步:調(diào)用你想要設(shè)置的某種屬性對應(yīng)的接口函數(shù)

? ? ? ? ? ? ? ? 第三步:讓你設(shè)置屬性生效

? ? ? ? ? ? ? ? ? ? ? ? pthread_create(id,attr,); //此時第二個參數(shù)一定不能寫成NULL

? ? ? ? ? ? ? ? 第四步:用完之后,銷毀

? ? ? ? ? ? ? ? ? ? ? ? int pthread_attr_destroy(pthread_attr_t *attr)

? ? ? ? ? 舉例:設(shè)置線程的分離屬性

? ? ? ? ? ? ? ? ? ? 線程分離:線程退出的時候,主線程不需要回收它,自己回收自己(自生自滅)

? ? ? ? ? ? ? ? ? ? 線程不可分離:線程退出的時候,主線程必須回收它,不回收就變成孤兒線程

? ? ? ? ? ? ? ? ? ? ? ? ? ? 線程默認的屬性是不可以分離

? ? ? ? (2)設(shè)置調(diào)度策略

? ? ? ? ? ? ? ? 第一種:SCHED_FIFO

? ? ? ? ? ? ? ? ? ? ? ? ? ? 靜態(tài)優(yōu)先級:0---99來劃分優(yōu)先級的級別

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 其中優(yōu)先級為0稱之為非實時普通線程

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 1-99稱之為實時線程,數(shù)字越大,優(yōu)先級越高

? ? ? ? ? ? ? ? 第二種:SCHED_RR

? ? ? ? ? ? ? ? 第三種:SCHED_OTHER? 默認的調(diào)度策略

? ? ? ? ? ? ? ? ? ? ? ? ? ? 靜態(tài)優(yōu)先級值必須是0,都是非實時普通線程

? ? ? ? ? ? ? ? ? ? ? ? ? ? 動態(tài)優(yōu)先級:取值 -20到19,數(shù)字越大,優(yōu)先級越低

線程的取消和設(shè)置取消類型

======================

? ? ? ? (1)線程的取消(干掉線程)

? ? ? ? ? ? ? int pthread_cancel(pthread_t thread);

? ? ? ? (2)設(shè)置取消類型和狀態(tài)

? ? ? ? ? ? ? int pthread_setcancelstate(int state, int *oldstate); //設(shè)置取消狀態(tài)(是否能被取消)

? ? ? ? ? ? ? ? ? ? ? ? 參數(shù):state --》

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? PTHREAD_CANCEL_DISABLE 不能取消

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? PTHREAD_CANCEL_ENABLE? 能被取消(線程默認是能被取消)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 分為兩種情況:延時取消和立即取消

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? oldstate --》存放線程原本的取消狀態(tài)

? ? ? ? ? ? ? int pthread_setcanceltype(int type, int *oldtype); //設(shè)置取消類型

? ? ? ? ? ? ? ? ? ? ? ? 參數(shù):type --》

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? PTHREAD_CANCEL_DEFERRED? 延時取消

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 線程被取消的時候會繼續(xù)往后執(zhí)行,直到遇到取消點結(jié)束

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 取消點:指的是linux規(guī)定的一系列函數(shù)


? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? PTHREAD_CANCEL_ASYNCHRONOUS? 立即取消(線程立馬退出)

線程的同步與互斥(重點)

=================

? ? 以下三種技術(shù)都是來協(xié)調(diào)線程的

? ? 前面學習進程間信號量:協(xié)調(diào)多個進程對于臨界區(qū)資源的訪問

? ? ? ? ? ? 臨界區(qū)資源:就是信號量協(xié)調(diào)保護的那一部分代碼

? ? (1)互斥鎖

? ? ? ? ? ? 作用:協(xié)調(diào)多個線程對于臨界區(qū)資源(共享資源,例如:全局變量)的訪問

? ? ? ? ? ? 學習方法:重點掌握互斥鎖的特點(前提條件是,多個線程操作同一把鎖)

? ? ? ? ? ? ? ? ? ? ? 哪個線程先上鎖,后上鎖的線程會阻塞,無法上鎖

? ? ? ? ? ? ? ? ? ? ? 上鎖操作要跟解鎖操作配合使用,如果只有上鎖,沒有解鎖(這個鎖稱之為死鎖)

? ? ? ? ? ? ? ? ? ? ? ? ? ? 死鎖:常見的情況有兩種

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 第一種:寫代碼的時候,有上鎖操作,但是沒有解鎖

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 第二種:線程剛一上鎖就被取消(來不及解鎖),導致死鎖

? ? ? ? ? ? 相關(guān)的接口函數(shù):

? ? ? ? ? ? ? ? 第一個函數(shù):互斥鎖的初始化

? ? ? ? ? ? ? ? ? int pthread_mutex_init(pthread_mutex_t *mutex,pthread_mutexattr_t *restrict attr);

? ? ? ? ? ? ? ? ? ? ? ? ? 參數(shù):mutex --》互斥鎖變量

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? attr --》互斥鎖的屬性,一般設(shè)置為NULL,表示使用默認屬性

? ? ? ? ? ? ? 第二個函數(shù):互斥鎖的使用

? ? ? ? ? ? ? ? ? ? int pthread_mutex_lock(pthread_mutex_t *mutex); //上鎖

? ? ? ? ? ? ? ? ? ? int pthread_mutex_trylock(pthread_mutex_t *mutex); //非阻塞上鎖


? ? ? ? ? ? ? ? ? ? int pthread_mutex_unlock(pthread_mutex_t *mutex); //解鎖

? ? ? ? ? ? ? 第三個函數(shù):互斥鎖銷毀

? ? ? ? ? ? ? ? ? ? int pthread_mutex_destroy(pthread_mutex_t *mutex);

? ? ? ? ? ? ? 第四個函數(shù):解決線程剛上鎖就被取消導致的死鎖

? ? ? ? ? ? ? ? ? ? void pthread_cleanup_push(void (*routine)(void *),void *arg);

? ? ? ? ? ? ? ? ? ? ? 注冊線程取消時需要處理的例程

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 參數(shù):

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? void (*routine)(void *) 函數(shù)指針

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? void *arg --》

? ? ? ? ? ? ? ? ? ? void pthread_cleanup_pop(int execute);

? ? ? ? ? ? ? ? ? ? ? 注意:這兩個函數(shù)是在線程被取消的時候發(fā)揮作用了,如果線程是正常退出,那么兩個函數(shù)不起作用



? ? (2)條件變量

? ? (3)信號量(線程)


條件變量

==============

? ? ? 1.作用:配合互斥鎖一起使用,不能單獨使用,滿足某個條件可以幫助你阻塞線程,同時也提供函數(shù)幫助你解除對線程的阻塞

? ? ? ? ? ? ? 滿足某個條件:這個條件是由程序員自己來寫的

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 例如:賣票的代碼,遇到票的數(shù)量為0,所有的窗口(線程)必須停止賣票

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 所以我的代碼的條件判斷就變成了if(當前票數(shù)==0){? 阻塞線程? }

? ? ? ? 特點:pthread_cond_wait()先解鎖,然后阻塞當前線程

? ? ? ? 使用經(jīng)驗分享:

? ? ? ? ? ? ? 使用條件變量:先思考清楚你的線程滿足什么條件需要阻塞


? ? ? 2.條件變量相關(guān)的接口函數(shù)

? ? ? ? ? ? 第一個函數(shù):條件變量的初始化

? ? ? ? ? ? ? int pthread_cond_init(pthread_cond_t *cond,pthread_condattr_t *attr);

? ? ? ? ? ? ? ? ? ? ? 參數(shù):pthread_cond_t --》表示條件變量

? ? ? ? ? ? ? ? ? ? ? ? ? ? attr --》設(shè)置為NULL,使用默認屬性

? ? ? ? ? ? 第二個函數(shù):條件變量的使用

? ? ? ? ? ? ? int pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex);//阻塞條件變量

? ? ? ? ? ? ? ? ? ? ? 參數(shù):cond --》剛才初始化好的條件變量

? ? ? ? ? ? ? ? ? ? ? ? ? ? mutex --》互斥鎖,條件變量需要跟鎖配合

? ? ? ? ? ? ? int pthread_cond_broadcast(pthread_cond_t *cond); //喚醒條件變量,喚醒所有的線程

? ? ? ? ? ? ? int pthread_cond_signal(pthread_cond_t *cond); //喚醒條件變量,只喚醒阻塞在條件變量上的某一個線程(解除條件變量的阻塞)

? ? ? ? ? ? 第三個函數(shù):銷毀條件變量

? ? ? ? ? ? ? int pthread_cond_destroy(pthread_cond_t *cond);

線程間的信號量

===============

? ? 1.原理:跟進程間信號量一模一樣

? ? 2.相關(guān)的接口函數(shù)

? ? ? ? ? (1)初始化信號量

? ? ? ? ? ? ? ? #include <semaphore.h>?

? ? ? ? ? ? ? ? int sem_init(sem_t *sem, int pshared, unsigned int value);

? ? ? ? ? ? ? ? ? ? ? 參數(shù):sem --》信號量

? ? ? ? ? ? ? ? ? ? ? ? ? ? pshared --》設(shè)置為0,表示信號量在線程間使用

? ? ? ? ? ? ? ? ? ? ? ? ? ? value --》信號量的值

? ? ? ? (2)信號量的pv操作?

? ? ? ? ? ? ? ? int sem_wait(sem_t *sem);? //p操作 -1

? ? ? ? ? ? ? ? int sem_post(sem_t *sem);? //v操作 +1

? ? ? ? (3)信號量的銷毀

? ? ? ? ? ? ? ? int sem_destroy(sem_t *sem);


線程池

===================

? ? ? 線程池:理解為是一個巨無霸"線程",本質(zhì)就是多個線程組成的一個集合

? ? ? 原理:說白了線程池的原理就是:

? ? ? ? ? ? ? ? 通過創(chuàng)建一個單鏈表(存函數(shù)指針),然后線程池里面的線程死命從單鏈表的頭結(jié)點取出任務(wù)處理

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 主函數(shù)負責往單鏈表中死命的添加任務(wù)

? ? ? 需要大家封裝如下三個核心函數(shù)

? ? ? ? ? (1)線程池的初始化

? ? ? ? ? ? ? ? threadpool_init();

? ? ? ? ? (2)任務(wù)鏈表的初始化和往任務(wù)鏈表中添加任務(wù)

? ? ? ? ? ? ? ? add_task();

? ? ? ? ? (3)銷毀線程池

? ? ? ? ? ? ? ? threadpool_destroy();?

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容