當前位置:首頁 » 操作系統 » linux庫函數

linux庫函數

發布時間: 2022-08-20 10:01:54

linux對動態庫函數的調用太慢

動態庫函數在載入程序時,資料庫將被載入。但是,動態載入程序鏈接器將符號解析推遲到函數調用時間。在對共享庫的調用是通過過程鏈接表(PLT)中的一個條目間接完成的。最初,PLT中的所有條目都指向ld.so。在第一次調用函數時,ld.so查找符號的實際地址,更新PLT中的條目,並跳轉到函數。這是「懶惰」符號解析。您可以設置LD_BIND_NOW環境變數來更改此行為。除此之外,試一下不用DLL直接把函數卸載程序里的運行速度,如果仍然慢,那就是演算法的問題。

⑵ Linux的庫函數是如何調用內核函數的

看系統調用,還有庫函數,以前一直不明白,總是以為 系統調用跟庫函數是一樣的,但是今天才知道是不一樣的。
庫函數也就是我們通常所說的應用編程介面API,它其實就是一個函數定義,比如常見read()、write()等函數說明了如何獲得一個給定的服務,但是系統調用是通過軟中斷向內核發出一個明確的請求,再者系統調用是在內核完成的,而用戶態的函數是在函數庫完成的。
系統調用發生在內核空間,因此如果在用戶空間的一般應用程序中使用系統調用來進行文件操作,會有用戶空間到內核空間切換的開銷。事實上,即使在用戶空間使用庫函數來對文件進行操作,因為文件總是存在於存儲介質上,因此不管是讀寫操作,都是對硬體(存儲器)的操作,都必然會引起系統調用。也就是說,庫函數對文件的操作實際上是通過系統調用來實現的。例如C庫函數fwrite()就是通過write()系統調用來實現的。
這樣的話,使用庫函數也有系統調用的開銷,為什麼不直接使用系統調用呢?這是因為,讀寫文件通常是大量的數據(這種大量是相對於底層驅動的系統調用所實現的數據操作單位而言),這時,使用庫函數就可以大大減少系統調用的次數。這一結果又緣於緩沖區技術。在用戶空間和內核空間,對文件操作都使用了緩沖區,例如用fwrite寫文件,都是先將內容寫到用戶空間緩沖區,當用戶空間緩沖區滿或者寫操作結束時,才將用戶緩沖區的內容寫到內核緩沖區,同樣的道理,當內核緩沖區滿或寫結束時才將內核緩沖區內容寫到文件對應的硬體媒介。
系統調用與系統命令:系統命令相對API更高一層,每個系統命令都是一個可執行程序,比如常用的系統命令ls、hostname等,比如strace ls就會發現他們調用了諸如open(),brk(),fstat(),ioctl()等系統調用。
系統調用是用戶進程進入內核的介面層,它本身並非內核函數,但他是由內核函數實現的,進入系統內核後,不同的系統調用會找到各自對應的內核函數,這寫內核函數被稱為系統調用的「服務常式」。也可以說系統調用是服務常式的封裝常式。

⑶ Linux下是否有文件拷貝的庫函數

不管是哪種操作系統,要實現文件拷貝,必須陷入內核,從磁碟讀取文件內容,然後存儲到另一個文件。實現文件拷貝最通常的做法是:讀取文件用系統調用read()函數,讀取到一定長度的連續的用戶層緩沖區,然後使用write()函數將緩沖區內容寫入文件。也可以用標准庫函數fread()和fwrite(),但這兩個函數最終還是通過系統調用read()和write()實現拷貝的,因此可以歸為一類(不過效率肯定沒有直接進行系統調用的高)。一個更高級的做法是使用虛擬存儲映射技術進行,這種方法將源文件以共享方式映射到虛擬存儲器中,目的文件也以共享方式映射到虛擬地址空間中,然後使用memcpy高效地將源文件內容復制到目的文件中。點擊(此處)折疊或打開#include#include#include#include#include#include#include#include#include#include#defineerror(fmt,args)\printf(fmt,##args);\printf(":%s\n",strerror(errno))inlineintcp_rw(intsrcfd,intdstfd,char*buf,intlen);inlineintcp_map(intsrcfd,intdstfd,size_tlen);intmain(intargc,char**argv){charbuf[8192];intsrcfd,dstfd;clock_tstart,end;structtmsstm,ntm;structstatfilestat;inttck;charcmdline[30];if(argc!=3)printf("usage:cmd");tck=sysconf(_SC_CLK_TCK);start=times(&stm);if((srcfd=open(argv[1],O_RDONLY))==-1){error("open%serror",argv[1]);exit(0);}if((dstfd=open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0666))==-1){error("creat%serror",argv[2]);exit(0);}fstat(srcfd,&filestat);if(lseek(dstfd,filestat.st_size,SEEK_SET)==-1){error("lseekerror");exit(0);}if(write(dstfd,"",1)!=1){error("writeerror");exit(0);}cp_map(srcfd,dstfd,filestat.st_size);close(srcfd);close(dstfd);end=times(&ntm);printf("ing%sto%susingcp_map:filesize=%luMBytesUsing%fseconds\n",argv[1],argv[2],filestat.st_size>>20,(end-start)/(double)tck);sprintf(cmdline,"rm-f%s",argv[2]);system(cmdline);return0;}inlineintcp_rw(intsrcfd,intdstfd,char*buf,intlen){intnread;while((nread=read(srcfd,buf,len))>0){if(write(dstfd,buf,nread)!=nread){error("writeerror");return-1;}}if(nread==-1){error("readerror");return-1;}return0;}inlineintcp_map(intsrcfd,intdstfd,size_tlen){char*src,*dst;if((src=mmap(0,len,PROT_READ,MAP_SHARED,srcfd,0))==MAP_FAILED){error("mmapsrcerror");return-1;}if((dst=mmap(0,len,PROT_WRITE,MAP_SHARED,dstfd,0))==MAP_FAILED){error("mmapdsterror");return-1;}if(memcpy(dst,src,len)==NULL){error("memcpyerror");return-1;}munmap(src,len);munmap(dst,len);return0;}運行,拷貝一個1.1G的文件,得到如下結果[root@garden]#.//home/ker.tgz./ker.tgzing/home/ker.tgzto./ker.tgzusingcp_map:filesize=1030MBytesUsing61.900000secondsing/home/ker.tgzto./ker.tgzusingcp_rw:filesize=1030MBytesUsing34.330000seconds使用read/write的方法居然比mmap的快一倍,這是怎麼回事呢?理論上mmap系統調用只進行了一次,而且拷貝文件是直接在內核空間進行的,read/write則需要通過系統調用把內核空間的緩存復制到用戶空間,再將用戶空間緩存復制到內核空間,拷貝次數明顯多了一個呢?速度為什麼於理論預測的不一致呢?

⑷ 怎麼在linux中查看庫函數源代碼

linux中查看庫函數源代碼,需要自己手動下載一個gnu libc源代碼庫。然後在裡面查,可以使用vim建立個ctags,然後及時定位到相應的函數即可。

⑸ 1.linux系統調用和庫函數調用的區別

系統調用:是操作系統為用戶態運行的進程和硬體設備(如CPU、磁碟、列印機等)進行交互提供的一組介面,即就是設置在應用程序和硬體設備之間的一個介面層。可以說是操作系統留給用戶程序的一個介面。再來說一下,linux內核是單內核,結構緊湊,執行速度快,各個模塊之間是直接調用的關系。放眼望整個linux系統,從上到下依次是用戶進程->linux內核->硬體。其中系統調用介面是位於Linux內核中的,如果再稍微細分一下的話,整個linux系統從上到下可以是:用戶進程->系統調用介面->linux內核子系統->硬體,也就是說Linux內核包括了系統調用介面和內核子系統兩部分;或者從下到上可以是:物理硬體->OS內核->OS服務->應用程序,其中操作系統起到「承上啟下」的關鍵作用,向下管理物理硬體,向上為操作系服務和應用程序提供介面,這里的介面就是系統調用了。
一般地,操作系統為了考慮實現的難度和管理的方便,它只提供一少部分的系統調用,這些系統調用一般都是由C和匯編混合編寫實現的,其介面用C來定義,而具體的實現則是匯編,這樣的好處就是執行效率高,而且,極大的方便了上層調用。
庫函數:顧名思義是把函數放到庫里。是把一些常用到的函數編完放到一個文件里,供別人用。別人用的時候把它所在的文件名用#include<>加到裡面就可以了。一般是放到lib文件里的。一般是指編譯器提供的可在c源程序中調用的函數。可分為兩類,一類是c語言標准規定的庫函數,一類是編譯器特定的庫函數。(由於版權原因,庫函數的源代碼一般是不可見的,但在頭文件中你可以看到它對外的介面)
libc中就是一個C標准庫,裡面存放一些基本函數,這些基本函數都是被標准化了的,而且這些函數通常都是用匯編直接實現的。
庫函數一般可以概括的分為兩類,一類是隨著操作系統提供的,另一類是由第三方提供的。隨著系統提供的這些庫函數把系統調用進行封裝或者組合,可以實現更多的功能,這樣的庫函數能夠實現一些對內核來說比較復雜的操作。比如,read()函數根據參數,直接就能讀文件,而背後隱藏的比如文件在硬碟的哪個磁軌,哪個扇區,載入到內存的哪個位置等等這些操作,程序員是不必關心的,這些操作裡面自然也包含了系統調用。而對於第三方的庫,它其實和系統庫一樣,只是它直接利用系統調用的可能性要小一些,而是利用系統提供的API介面來實現功能(API的介面是開放的)。部分Libc庫中的函數的功能的實現還是藉助了系統掉調用,比如printf的實現最終還是調用了write這樣的系統調用;而另一些則不會使用系統調用,比如strlen,
strcat,
memcpy等。
實時上,系統調用所提供給用戶的是直接而純粹的高級服務,如果想要更人性化,具有更符合特定情況的功能,那麼就要我們用戶自己來定義,因此就衍生了庫函數,它把部分系統調用包裝起來,一方面把系統調用抽象了,一方面方便了用戶級的調用。系統調用和庫函數在執行的效果上很相似(當然庫函數會更符合需求),但是系統調用是運行於內核狀態;而庫函數由用戶調用,運行於用戶態。
系統調用是為了方便使用操作系統的介面,而庫函數則是為了人們編程的方便。

⑹ linux中標准庫函數和非標准庫函數的區別是什麼

我也不是很清楚,談談我的理解,以c語言為例,安裝c編譯器,裡面都自帶一些功能函數庫,但不同編譯器廠商提供不同的庫以及不同的頭文件,實際上不利於程序的移植和發展,標准庫的出現實際上是統一了這個標准,提供了標准頭文件。而非標准實際上就是自定義的一些頭文件。從使用上來說,標准頭文件用<>,編譯時在系統路徑中查找,自定義頭文件用"",編譯時在用戶目錄搜索。希望對你有幫助

⑺ linuxc語言函數庫在什麼路徑

一般來說是放在/usr/include目錄下的;
但是這個並不局限也是可控的,如果我們進行開發過程中,
就會在內核的庫函數文件目錄:
例如在:/XXX/XXX/linux-X.X/include
所以根據不同的情況,頭文件存放的目錄也是不同的,具體需要可以根據locate和grep命令進行查詢。

熱點內容
雜訊的危害和控制設計腳本 發布:2025-05-17 08:22:29 瀏覽:472
esr演算法 發布:2025-05-17 08:16:09 瀏覽:194
安卓手機怎麼用擬我表情 發布:2025-05-17 08:10:13 瀏覽:918
給U盤安裝kalilinux 發布:2025-05-17 08:07:26 瀏覽:249
sql提示存儲過程 發布:2025-05-17 07:35:58 瀏覽:743
qq里的互動訪問 發布:2025-05-17 07:26:53 瀏覽:665
口語易賬號密碼發送到哪裡 發布:2025-05-17 07:26:52 瀏覽:62
核桃編程幼兒 發布:2025-05-17 07:26:50 瀏覽:787
2台伺服器集群搭建 發布:2025-05-17 07:18:57 瀏覽:185
北方園林配置植物有哪些 發布:2025-05-17 07:18:20 瀏覽:544