新聞中心
小眾技巧:使用Linux C中的暫停語(yǔ)句提高程序運(yùn)行效率!

十多年建站經(jīng)驗(yàn), 網(wǎng)站設(shè)計(jì)、網(wǎng)站制作客戶(hù)的見(jiàn)證與正確選擇。成都創(chuàng)新互聯(lián)提供完善的營(yíng)銷(xiāo)型網(wǎng)頁(yè)建站明細(xì)報(bào)價(jià)表。后期開(kāi)發(fā)更加便捷高效,我們致力于追求更美、更快、更規(guī)范。
在軟件開(kāi)發(fā)中,提高程序運(yùn)行效率一直是程序員們追求的目標(biāo)之一。在Linux C編程中,有許多技巧可以提高程序的運(yùn)行效率,其中使用暫停語(yǔ)句可以說(shuō)是一個(gè)小眾技巧,但是卻非常有效。本文將會(huì)介紹什么是暫停語(yǔ)句,暫停語(yǔ)句的實(shí)現(xiàn)方式,以及如何有效地將暫停語(yǔ)句應(yīng)用于Linux C的程序開(kāi)發(fā)中。
一、什么是暫停語(yǔ)句?
在Linux C中,暫停語(yǔ)句指的是通過(guò)系統(tǒng)調(diào)用sleep()來(lái)實(shí)現(xiàn),該函數(shù)的主要作用是使當(dāng)前進(jìn)程暫停一段時(shí)間,讓出CPU的使用權(quán),以避免CPU的占用過(guò)度,從而達(dá)到提高程序運(yùn)行效率的目的。當(dāng)程序執(zhí)行到sleep()函數(shù)時(shí),程序會(huì)進(jìn)入阻塞狀態(tài),等待固定的時(shí)間后再次運(yùn)行。
二、暫停語(yǔ)句的實(shí)現(xiàn)方式
在Linux C編程中,實(shí)現(xiàn)暫停語(yǔ)句非常簡(jiǎn)單,只需要調(diào)用sleep()函數(shù)即可。例如,下面的示例代碼展示了如何使用sleep()函數(shù)創(chuàng)建一個(gè)簡(jiǎn)單的暫停程序:
#include
#include
int mn()
{
printf(“Begin Pause\n”);
sleep(10);
printf(“End Pause\n”);
return 0;
}
在上面的代碼中,我們調(diào)用了sleep()函數(shù),并傳遞了一個(gè)參數(shù)10,表示程序暫停10秒鐘。在執(zhí)行到sleep()函數(shù)時(shí),程序會(huì)睡眠10秒鐘,然后打印出”End Pause”這句話(huà)。這個(gè)示例程序非常簡(jiǎn)單,但是卻可以讓我們清楚地看到暫停語(yǔ)句的實(shí)現(xiàn)方式。
除了使用sleep()函數(shù)之外,還有一些其他的方法可以實(shí)現(xiàn)暫停語(yǔ)句。例如,我們可以使用usleep()函數(shù)來(lái)實(shí)現(xiàn)微秒級(jí)的暫停操作,也可以使用nanosleep()函數(shù)來(lái)實(shí)現(xiàn)納秒級(jí)的暫停操作。
三、如何有效地應(yīng)用暫停語(yǔ)句于Linux C程序開(kāi)發(fā)中
雖然暫停語(yǔ)句可以提高程序的運(yùn)行效率,但是過(guò)度地使用暫停語(yǔ)句會(huì)導(dǎo)致程序變慢或者出現(xiàn)諸如卡頓等問(wèn)題。因此,在Linux C程序開(kāi)發(fā)中,應(yīng)該合理地應(yīng)用暫停語(yǔ)句,從而達(dá)到更好的效果。
下面是一些使用暫停語(yǔ)句的小技巧:
1. 合理地設(shè)置暫停時(shí)間
在Linux C編程中,應(yīng)該合理地設(shè)置暫停時(shí)間,避免浪費(fèi)CPU時(shí)間。如果暫停時(shí)間過(guò)短,程序可能會(huì)頻繁地調(diào)用sleep()函數(shù),從而浪費(fèi)CPU時(shí)間;如果暫停時(shí)間過(guò)長(zhǎng),程序可能會(huì)變慢或者出現(xiàn)諸如”卡頓”等問(wèn)題。因此,我們應(yīng)該根據(jù)具體情況來(lái)確定暫停時(shí)間。
2. 避免在循環(huán)中過(guò)度使用暫停語(yǔ)句
在使用暫停語(yǔ)句時(shí),應(yīng)該避免在循環(huán)中過(guò)度使用,否則會(huì)導(dǎo)致程序變慢。應(yīng)該僅在必要時(shí)使用暫停語(yǔ)句。
3. 考慮使用其他的調(diào)度機(jī)制
在某些情況下,應(yīng)該考慮使用其他的調(diào)度機(jī)制,例如信號(hào)和定時(shí)器。這些機(jī)制可以實(shí)現(xiàn)和暫停語(yǔ)句類(lèi)似的功能,但是更為靈活和高效。
小結(jié)
相關(guān)問(wèn)題拓展閱讀:
- Linux C中的Socket,shutdown函數(shù)和close函數(shù)有什么不同
- 求解答,“l(fā)inux中終端控制鍵Ctrl+C,Ctrl+Z,Ctrl+D的使用場(chǎng)合”
Linux C中的Socket,shutdown函數(shù)和close函數(shù)有什么不同
shutdown并不蘆則臘會(huì)關(guān)閉socket decriptor,只是改變其工作方式盯余。而close則會(huì)釋放陪滑這個(gè)socket。
假設(shè)server和client 已經(jīng)建立了連接,server調(diào)用了close, 發(fā)送FIN 段給client(其實(shí)不一定會(huì)發(fā)送FIN段,后面再說(shuō)),此時(shí)server不能再通過(guò)
socket發(fā)送和接收數(shù)據(jù),此時(shí)client調(diào)用read,如果接收到FIN 段會(huì)返回0,但client此時(shí)還是可以write 給server的,write調(diào)用只負(fù)責(zé)把數(shù)據(jù)交給TCP
發(fā)送緩沖區(qū)就可以成功返回了,所以不會(huì)出錯(cuò),而server收到數(shù)據(jù)后應(yīng)答一個(gè)RST段,表示服務(wù)器已經(jīng)不能接收數(shù)據(jù),連接重置,client收到RST段后無(wú)
法立刻通知應(yīng)用層,只把這個(gè)狀態(tài)保存在TCP協(xié)議層。如果client再次調(diào)用攔枝跡write發(fā)數(shù)據(jù)給server,由于TCP協(xié)議層已經(jīng)處于RST狀態(tài)了,因此不會(huì)將數(shù)據(jù)
發(fā)出,而是發(fā)一個(gè)SIGPIPE信號(hào)給應(yīng)用層,SIGPIPE信號(hào)的缺省處理動(dòng)作是終止程序。
有時(shí)候代碼中需要連續(xù)多次調(diào)用write,可能還來(lái)不及調(diào)用read得知對(duì)方已關(guān)閉了連接就被SIGPIPE信號(hào)終止掉了,這就需要在初始化時(shí)調(diào)用sigaction處
理SIGPIPE信號(hào),對(duì)于這個(gè)信號(hào)的處理我們通常忽略即可,signal(SIGPIPE, SIG_IGN); 如果SIGPIPE信號(hào)沒(méi)有導(dǎo)致進(jìn)程異常退出,write返回-1并且
errno為EPIPE。
#include
intclose(int fd);
close 關(guān)閉了自身數(shù)據(jù)傳輸?shù)膬蓚€(gè)方向。
#include
intshutdown(int sockfd, int how);
shutdown 可以選擇關(guān)閉某個(gè)方向或者同時(shí)關(guān)閉兩個(gè)方向,shutdownhow = 1 or how = 2 (SHUT_WR or SHUT_RDWR),可以保證對(duì)等方接收到一個(gè)EOF字符(即發(fā)送了一個(gè)FIN段),而不管其他進(jìn)程是否已經(jīng)打開(kāi)了這個(gè)套接字。而close不能保證,只有當(dāng)某個(gè)sockfd的引用計(jì)數(shù)為0,close 才會(huì)發(fā)送FIN段,否則只是將引用計(jì)數(shù)減1而已。也就是說(shuō)只有當(dāng)所有進(jìn)程(可能fork多個(gè)子進(jìn)程都打開(kāi)了這個(gè)套接字)都關(guān)閉了這個(gè)套接字,close 才會(huì)發(fā)送FIN段。
所以說(shuō),如果是調(diào)用shutdown how = 1 ,則意味著往一個(gè)已經(jīng)接收FIN的套接字中寫(xiě)是簡(jiǎn)并允許的,接收到FIN段僅代表對(duì)方不再發(fā)送數(shù)據(jù),但對(duì)方還是可以讀取數(shù)據(jù)的,可以讓對(duì)方可以繼續(xù)讀取緩沖區(qū)剩余的數(shù)據(jù)。
下面使用shutdown 修改客戶(hù)端程序,在前面講過(guò)的使用select函數(shù)修改后的客戶(hù)端程序基礎(chǔ)上,修改很小一部分:
C++ Code
if (FD_ISSET(fd_stdin, &rset))
{
if (fgets(sendbuf, sizeof(sendbuf), stdin)== NULL)
{
stdineof = 1; //表示已經(jīng)輸入完畢
/* 關(guān)閉sock的寫(xiě)端,還能夠接收數(shù)據(jù),在sock的緩沖區(qū)末尾添加一個(gè)FIN段 */
shutdown(sock, SHUT_WR);
}
else
{
writen(sock, sendbuf, strlen(sendbuf));
memset(sendbuf, 0, sizeof(sendbuf));
}
}
為了測(cè)試我們想要的效果,需要在select函數(shù)修改后的服務(wù)器端程序的 134 行代碼之后,即writen 之前 sleep(4); 目的是接收到客戶(hù)端數(shù)據(jù)后搭帶不馬
上回射回去,睡眠4s 后在客戶(hù)端已經(jīng)關(guān)閉連接的情況下再發(fā)送數(shù)據(jù)。
先運(yùn)行服務(wù)器端程序,再運(yùn)行客戶(hù)端程序,在客戶(hù)端標(biāo)準(zhǔn)輸入,迅速敲入兩行:AAAAA\n BBBBB\n 然后按下ctrl+d 即fgets 會(huì)返回NULL,然后調(diào)用
shutdown關(guān)閉寫(xiě)端,雖然服務(wù)器端延時(shí)才發(fā)送數(shù)據(jù),此時(shí)客戶(hù)端寫(xiě)端已經(jīng)關(guān)閉,但還是可以讀取到回射回來(lái)的數(shù)據(jù),服務(wù)器端最后得到一個(gè)FIN段,read
返回0,打印輸出 client close ,并且close(conn); 而客戶(hù)端在讀取服務(wù)端回射回來(lái)的兩次數(shù)據(jù)后,再次read 也返回0,故打印 server connect
close,break退出循環(huán),進(jìn)程順利退出。從下面的輸出還可以看出,因?yàn)檠訒r(shí)的關(guān)系,所以不像以前那樣發(fā)射一行就回射一行。
simba@ubuntu:~/Documents/code/linux_programming/UNP/socket$./echoser_select
recv connect ip=127.0.0.1 port=54010
fdsgfgd
gfedg
client close
………………………
simba@ubuntu:~/Documents/code/linux_programming/UNP/socket$./echocli_select_shutdown
local ip=127.0.0.1 port=54010
fdsgfgd
gfedg
fdsgfgd
gfedg
gfedg
server connect close
如果我們將客戶(hù)端程序中的shutdown 改成了 close,那么當(dāng)延時(shí)后服務(wù)器端發(fā)送數(shù)據(jù)給客戶(hù)端時(shí),客戶(hù)端的讀端和寫(xiě)端都已經(jīng)關(guān)閉,之一次發(fā)AAAAA會(huì)
返回一個(gè)RST段,根據(jù)本文前面所說(shuō),再次發(fā)BBBBB直接產(chǎn)生SIGPIPE信號(hào),默認(rèn)會(huì)終止進(jìn)程,但因?yàn)槲覀円呀?jīng)設(shè)置了忽略SIGPIPE信號(hào),所以服務(wù)器端進(jìn)
程不會(huì)被終止,但客戶(hù)端也會(huì)出錯(cuò),因?yàn)榛氐絯hile循環(huán)開(kāi)頭,select阻塞等待時(shí)發(fā)現(xiàn)套接字的讀端已經(jīng)關(guān)閉,所以不能再關(guān)心可讀事件了,select會(huì)返
回-1,錯(cuò)誤碼是 EBADF: Bad File Descriptor。
老問(wèn)題了。網(wǎng)上有人說(shuō)的挺清楚的,請(qǐng)百度“socket shutdown close區(qū)別”。
求解答,“l(fā)inux中終端控制鍵Ctrl+C,Ctrl+Z,Ctrl+D的使用場(chǎng)合”
C=Close
Z=Pause
D=Delete
呵呵 這幾個(gè)快捷鍵的確很相似,但是功能又不相同,簡(jiǎn)單說(shuō)下:
1、Ctrl+C比較暴力,就是發(fā)送Terminal到當(dāng)前搭巧的程序,比如你正在運(yùn)行一個(gè)查找功能,文件正在查找中,Ctrl+C就會(huì)強(qiáng)制結(jié)束當(dāng)前的這個(gè)進(jìn)程。
2、Ctrl+Z是把當(dāng)前的程序掛起,暫停執(zhí)行這知滾鍵個(gè)程序,比如你正在mysql終端中,需要出來(lái)搞點(diǎn)其他的文件操作,又不想退出mysql終端(因?yàn)橄麓芜€得輸入用戶(hù)名密碼進(jìn)入,挺麻煩),于是可以ctrl+z將mysql掛起,然后進(jìn)行其他操作,然后輸入fg回車(chē)后就可以回來(lái),當(dāng)然可以?huà)炱鸷枚噙M(jìn)程到后臺(tái),然后fg 加備洞編號(hào)就能把掛起的進(jìn)程返回到前臺(tái)。當(dāng)然,配合bg和fg命令進(jìn)行前后臺(tái)切換會(huì)非常方便。
3、Ctrl+D 是發(fā)送一個(gè)exit信號(hào),沒(méi)有那么強(qiáng)烈,類(lèi)似ctrl+C的操作,比如你從管理員root退回到你的普通用戶(hù)就可以這么用。
Good Luck~~
Ctrl+C 終止一個(gè)程序的運(yùn)行,如:你不想繼續(xù)當(dāng)前程序的運(yùn)行,可以用這個(gè)命令終渣賣(mài)液止,回配鍵到提如物示符下。
Ctrl+Z 掛起一個(gè)當(dāng)前運(yùn)行的程序
Ctrl+D 退出當(dāng)前的SHELL,相當(dāng)于exit命令
關(guān)于linux c 暫停語(yǔ)句的介紹到此就結(jié)束了,不知道你從中找到你需要的信息了嗎 ?如果你還想了解更多這方面的信息,記得收藏關(guān)注本站。
成都服務(wù)器托管選創(chuàng)新互聯(lián),先上架開(kāi)通再付費(fèi)。
創(chuàng)新互聯(lián)(www.cdcxhl.com)專(zhuān)業(yè)-網(wǎng)站建設(shè),軟件開(kāi)發(fā)老牌服務(wù)商!微信小程序開(kāi)發(fā),APP開(kāi)發(fā),網(wǎng)站制作,網(wǎng)站營(yíng)銷(xiāo)推廣服務(wù)眾多企業(yè)。電話(huà):028-86922220
名稱(chēng)欄目:小眾技巧:使用linux c中的暫停語(yǔ)句提高程序運(yùn)行效率! (linux c 暫停語(yǔ)句)
分享鏈接:http://www.fisionsoft.com.cn/article/coidsji.html


咨詢(xún)
建站咨詢(xún)
