最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深入學(xué)習(xí)C語言mmap和shm*的使用方法技巧

 更新時間:2023年10月09日 10:05:12   作者:Lion?Long  
本文將詳細(xì)介紹mmap和shm的工作原理,包括它們在內(nèi)存映射和共享內(nèi)存方面的優(yōu)勢和適用場景,同時,文章還會分享一些使用mmap和shm的技巧和經(jīng)驗,以幫助讀者優(yōu)化并提高程序性能,使你能夠在實際項目中更好地利用這些技術(shù)來加速數(shù)據(jù)共享和多線程應(yīng)用

一、背景

共享內(nèi)存使用場景:當(dāng)有一個超大的文件,如何能快速的讀寫?

文件是存儲在磁盤上的,要快速的讀寫一個大文件,可以通過共享內(nèi)存的方式(mmap等)。mmap內(nèi)部是使用的DMA技術(shù),DMA是內(nèi)存和磁盤之間的傳輸方式,有自己的指令,不需要CPU的參與。

零拷貝技術(shù):我們常說的拷貝,是需要CPU參與的,通過CPU指令將文件內(nèi)容復(fù)制一份到內(nèi)存中。所謂的零拷貝,就是不需要CPU的參與,而不是其他的意思。零拷貝有mmap和shm*接口這些方式實現(xiàn)。

二、內(nèi)存映射mmap

應(yīng)用程序和內(nèi)核或磁盤直接數(shù)據(jù)交互,可以通過映射內(nèi)存塊的方式。

mmap():將文件或設(shè)備映射到內(nèi)存。

munmap():將文件或設(shè)備取消映射到內(nèi)存。

函數(shù)原型:

#include <sys/mman.h>
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
int munmap(void *addr, size_t length);

mmap的內(nèi)存即不在堆也不在棧上,是一塊獨立的空間。

2.1、mmap()

mmap()在調(diào)用進(jìn)程的虛擬地址空間中創(chuàng)建一個新的映射。新映射的起始地址在addr中指定。length參數(shù)指定映射的長度。

如果addr為空,則內(nèi)核選擇創(chuàng)建映射的地址;這是創(chuàng)建新映射的最可移植方法。 如果addr不為空,則內(nèi)核將其作為一個提示,提示將映射放置在何處;在Linux上,映射將在附近的頁面邊界處創(chuàng)建。新映射的地址作為調(diào)用的結(jié)果返回。

文件映射的內(nèi)容(與匿名映射相反;參見下面的MAP_MAP_ANONYMOUS)使用文件描述符fd所引用的文件(或其他對象)中從偏移量offset開始的length字節(jié)進(jìn)行初始化。offset必須是sysconf(_SC_PAGE_SIZE)返回的頁面大小的倍數(shù)。

prot參數(shù)描述了映射所需的內(nèi)存保護(hù)(不得與文件的打開模式?jīng)_突)。它是PROT_NONE或以下一個或多個標(biāo)志的位OR:

標(biāo)志含義
PROT_EXEC可以執(zhí)行頁面。
PROT_READ可以讀取頁面。
PROT_WRITE可以寫入頁面。
PROT_NONE可能無法訪問頁面。

flags參數(shù)確定映射的更新是否對映射相同區(qū)域的其他進(jìn)程可見,以及更新是否傳遞到基礎(chǔ)文件。通過在標(biāo)志中包含以下值中的一個來確定此行為:

標(biāo)志含義
MAP_SHARED共享此映射。對映射的更新對映射此文件的其他進(jìn)程可見,并會傳遞到基礎(chǔ)文件。(要精確控制對底層文件進(jìn)行更新的時間,需要使用msync())
MAP_PRIVATE創(chuàng)建寫時私有副本映射。映射的更新對于映射同一文件的其他進(jìn)程不可見,并且不會傳遞到基礎(chǔ)文件。未指定在mmap()調(diào)用后對文件所做的更改是否在映射區(qū)域中可見。

此外,以下值中的零個或多個可以在flag中進(jìn)行“或”運算:

標(biāo)志含義
MAP_32B5IT(自Linux 2.4.20、2.6起)將映射放入進(jìn)程地址空間的前2千兆字節(jié)。對于64位程序,此標(biāo)志僅在x86-64上受支持。添加它是為了允許在第一個2GB內(nèi)存中的某個位置分配線程堆棧,從而提高早期64位處理器上的上下文切換性能?,F(xiàn)代x86-64處理器不再存在此性能問題,因此在這些系統(tǒng)上不需要使用此標(biāo)志。當(dāng)設(shè)置MAP_ FIXED時,MAP_32BIT標(biāo)志被忽略。
MAP_ANONMAP_ANONYMOUS的同義詞。不贊成。
MAP_ANONYMOUS映射沒有任何文件支持;其內(nèi)容被初始化為零。忽略fd和offset參數(shù);然而,如果指定了MAP_ANONYMOUS(或MAP_ANON),則某些實現(xiàn)要求fd為-1,可移植應(yīng)用程序應(yīng)確保這一點。只有從內(nèi)核2.4開始,Linux才支持將MAP_ANONYMOUS與MAP_SHARED結(jié)合使用。
MAP_DENYWRITE忽略此標(biāo)志。(很久以前,它發(fā)出了一個信號,表示嘗試寫入底層文件時,ETXTBUSY會失敗。但這是拒絕服務(wù)攻擊的一個來源。)
MAP_EXECUTABLE忽略此標(biāo)志。
MAP_FILE兼容性標(biāo)志。忽略。

返回值:成功后,mmap()返回指向映射區(qū)域的指針。錯誤時,返回值MAP_FAILED(即,(void*)-1),并設(shè)置errno以指示錯誤原因。

2.2、munmap()

munmap()系統(tǒng)調(diào)用刪除指定地址范圍的映射,并導(dǎo)致對該范圍內(nèi)地址的進(jìn)一步引用生成無效內(nèi)存引用。當(dāng)進(jìn)程終止時,區(qū)域也會自動取消映射。另一方面,關(guān)閉文件描述符不會取消區(qū)域映射。

地址addr必須是頁面大小的倍數(shù)(但長度不必是)。包含指定范圍一部分的所有頁面均未映射,對這些頁面的后續(xù)引用將生成SIGSEGV。如果指示的范圍不包含任何映射頁,則不是錯誤。

返回值:成功時,munmap()返回0。失敗時,它返回-1,errno被設(shè)置為指示錯誤原因(可能是EINVAL)。

錯誤代碼

錯誤代碼含義
EACCES文件描述符指的是非常規(guī)文件?;蛘哒埱罅宋募成?,但fd未打開讀取?;蛘哒埱驧AP_SHARED并且設(shè)置PROT_WRITE,但fd在讀/寫(O_RDWR)模式下未打開。或者設(shè)置了PROT_WRITE,但該文件僅為append。
EAGAIN文件已鎖定,或已鎖定過多內(nèi)存【請參閱setrlimit()】。
EBADFfd不是有效的文件描述符(并且未設(shè)置MAP_ANONYMOUS)。
EINVAL我們不喜歡addr、length或offset(例如,它們太大,或者在頁面邊界上沒有對齊)。(自Linux 2.6.12起)length為0。
EINVAL標(biāo)志既不包含MAP_PRIVATE也不包含MAP_SHARED,或者同時包含這兩個值。
ENFILE已達(dá)到系統(tǒng)范圍內(nèi)打開文件總數(shù)的限制。
ENODEV指定文件的底層文件系統(tǒng)不支持內(nèi)存映射。
ENOMEM沒有可用的內(nèi)存。
ENOMEM進(jìn)程的最大映射數(shù)將被超過。當(dāng)在現(xiàn)有映射的中間取消映射區(qū)域時,munmap()也會出現(xiàn)此錯誤,因為這會導(dǎo)致在未映射區(qū)域的任一側(cè)出現(xiàn)兩個較小的映射。
EPERMprot參數(shù)要求PORT_EXEC,但映射區(qū)域?qū)儆谖窗惭bEXEC的文件系統(tǒng)上的文件。
EPERM文件封條阻止了該操作;見fcntl()。
ETXTBSYMAP_DENYWRITE已設(shè)置,但fd指定的對象已打開寫入。
EOVERFLOW在32位體系結(jié)構(gòu)和大文件擴展名(即使用64位off_t)上:用于長度的頁數(shù)加上用于偏移量的頁數(shù)將溢出無符號長(32位)。

使用映射區(qū)域可產(chǎn)生以下信號:

信號含義
SIGSEGV試圖寫入映射為只讀的區(qū)域。
SIGBUS試圖訪問緩沖區(qū)中與文件不對應(yīng)的部分(例如,超出文件末尾,包括另一個進(jìn)程截斷文件的情況)。

2.3、流程

(1)打開文件

(2)取文件大小

(3)把文件映射成虛擬內(nèi)存

(4)通過對內(nèi)存的讀寫來實現(xiàn)對文件的讀寫

(5)卸載映射

(6)關(guān)閉文件

2.4、示例代碼

#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define handle_error(msg) \
    do { perror(msg); exit(EXIT_FAILURE); } while (0)
int main(int argc, char *argv[])
{
    char *addr;
    int fd;
    struct stat sb;
    off_t offset, pa_offset;
    size_t length;
    ssize_t s;
    if (argc < 3 || argc > 4) {
        fprintf(stderr, "%s file offset [length]\n", argv[0]);
        exit(EXIT_FAILURE);
    }
    fd = open(argv[1], O_RDONLY);
    if (fd == -1)
        handle_error("open");
    if (fstat(fd, &sb) == -1)           /* To obtain file size */
        handle_error("fstat");
    offset = atoi(argv[2]);
    pa_offset = offset & ~(sysconf(_SC_PAGE_SIZE) - 1);
        /* offset for mmap() must be page aligned */
    if (offset >= sb.st_size) {
        fprintf(stderr, "offset is past end of file\n");
        exit(EXIT_FAILURE);
    }
    if (argc == 4) {
        length = atoi(argv[3]);
        if (offset + length > sb.st_size)
            length = sb.st_size - offset;
                /* Can't display bytes past end of file */
    } else {    /* No length arg ==> display to end of file */
        length = sb.st_size - offset;
    }
    addr = mmap(NULL, length + offset - pa_offset, PROT_READ,
                MAP_PRIVATE, fd, pa_offset);
    if (addr == MAP_FAILED)
        handle_error("mmap");
    s = write(STDOUT_FILENO, addr + offset - pa_offset, length);
    if (s != length) {
        if (s == -1)
            handle_error("write");
        fprintf(stderr, "partial write");
        exit(EXIT_FAILURE);
    }
    exit(EXIT_SUCCESS);
}

三、shm*接口

共享內(nèi)存就是允許兩個不相關(guān)的進(jìn)程訪問同一個內(nèi)存塊。共享內(nèi)存是在兩個正在運行的進(jìn)程之間共享和傳遞數(shù)據(jù)的一種非常有效的方式。進(jìn)程可以將同一段共享內(nèi)存連接到它們自己的地址空間中,所有進(jìn)程都可以訪問共享內(nèi)存中的地址。而如果某個進(jìn)程向共享內(nèi)存寫入數(shù)據(jù),所做的改動將立即影響到可以訪問同一段共享內(nèi)存的任何其他進(jìn)程。

共享內(nèi)存并未提供同步機制,也就是說,在第一個進(jìn)程結(jié)束對共享內(nèi)存的寫操作之前,并無自動機制可以阻止第二個進(jìn)程開始對它進(jìn)行讀取。所以,通常需要用其他的機制來同步對共享內(nèi)存的訪問,例如信號量。

3.1、shmget()

創(chuàng)建共享內(nèi)存。函數(shù)原型:

#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);

描述:shmget()返回與參數(shù)key的值關(guān)聯(lián)的System V共享內(nèi)存段的標(biāo)識符。如果key的值為IPC_PRIVATE或key不是IPC_PRIVATE,不存在與key對應(yīng)的共享內(nèi)存段,并且在shmflg中指定了IPC_CREAT,則會創(chuàng)建一個大小等于size值的新共享內(nèi)存段(向上舍入為PAGE_SIZE的倍數(shù))。

如果shmflg同時指定IPC_CREAT和IPC_ EXCL,并且key已經(jīng)存在共享內(nèi)存段,則shmget()將失敗,錯誤號設(shè)置為EEXIST?!具@類似于open()的組合O_CREAT|O_EXCL的效果。】

值shmflg由以下組成:

標(biāo)志含義
IPC_CREAT創(chuàng)建新段。如果未使用此標(biāo)志,則shmget()將查找與鍵關(guān)聯(lián)的段,并檢查用戶是否有訪問該段的權(quán)限。
IPC_EXCL此標(biāo)志與IPC_ CREAT一起使用,以確保此調(diào)用創(chuàng)建段。如果段已經(jīng)存在,則調(diào)用失敗。
SHM_HUGETLB(自Linux 2.6起)使用“巨大頁面”分配段。
SHM_HUGE_2MB、SHM_ HUGE _1GB(自Linux 3.8起)與SHM_HUGETLB結(jié)合使用,在支持多種HUGETLB頁面大小的系統(tǒng)上選擇可選的HUGETLB頁大?。ǚ謩e為2 MB和1 GB)。更一般地,可以通過在偏移SHM_SHAGE_SHIFT處對六位中的期望頁面大小的以2為底的對數(shù)進(jìn)行編碼來配置期望的巨大頁面大小。因此,上述兩個常數(shù)定義為:#define SHM_HUGE_2MB (21 << SHM_HUGE_SHIFT) 和 #define SHM_HUGE_1GB (30 << SHM_HUGE_SHIFT)
SHM_NORESERVE(自Linux 2.6.15起)該標(biāo)志的作用與mmap() MAP_NORESERVE標(biāo)志相同。不要為此段保留交換空間。當(dāng)保留交換空間時,可以保證可以修改段。當(dāng)交換空間未保留時,如果沒有可用的物理內(nèi)存,則在寫入時可能會得到SIGSEGV。

除上述標(biāo)志外,shmflg的最低有效9位指定授予所有者、組和其他人的權(quán)限。這些位的格式和含義與open()的模式參數(shù)相同。目前,系統(tǒng)不使用執(zhí)行權(quán)限。

返回值:成功后,將返回有效的共享內(nèi)存標(biāo)識符。出現(xiàn)錯誤時,返回-1,并設(shè)置errno以指示錯誤。

錯誤:失敗時,錯誤號設(shè)置為以下之一:

錯誤代碼含義
EACCES用戶沒有訪問共享內(nèi)存段的權(quán)限,并且沒有CAP_IPC_OWNER功能。
EEXIST在shmflg中指定了IPC_CREAT和IPC_ EXCL,但密鑰的共享內(nèi)存段已經(jīng)存在。
EINVAL將創(chuàng)建一個新的段,其大小小于SHMMIN或大于SHMMAX。
EINVAL給定鍵的段存在,但大小大于該段的大小。
ENFILE已達(dá)到系統(tǒng)范圍內(nèi)打開文件總數(shù)的限制。
ENOENT給定密鑰不存在任何段,并且未指定IPC_CREAT。
ENOMEM無法為段開銷分配內(nèi)存。
ENOSPC已獲取所有可能的共享內(nèi)存ID(SHMMNI),或者分配請求大小的段將導(dǎo)致系統(tǒng)超過系統(tǒng)范圍內(nèi)的限制共享內(nèi)存(SHMALL)。
EPERM指定了SHM_HUGETLB標(biāo)志,但調(diào)用方?jīng)]有特權(quán)(沒有CAP_IPC_LOCK功能)。

3.2、shmat()

啟動對該共享內(nèi)存的訪問,并把共享內(nèi)存連接到當(dāng)前進(jìn)程的地址空間,函數(shù)原型:

#include <sys/types.h>
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int shmflg);

描述:shmat()將由shmid標(biāo)識的System V共享內(nèi)存段附加到調(diào)用進(jìn)程的地址空間。附加地址由shmaddr根據(jù)以下標(biāo)準(zhǔn)之一指定:

(1)如果shmaddr為空,系統(tǒng)將選擇一個合適的(未使用的)地址來連接段。

(2)如果shmaddr不為空,并且在shmflg中指定了SHM_RND,則附加發(fā)生在等于shmaddr的地址處,向下舍入到SHMLBA的最近倍數(shù)。

(3)否則,shmaddr必須是發(fā)生附加的頁對齊地址。

除了SHM_RND,還可以在shmflg位掩碼參數(shù)中指定以下標(biāo)志:

標(biāo)志含義
SHM_EXEC(特定于Linux;自Linux 2.6.9起)允許執(zhí)行段的內(nèi)容。調(diào)用者必須對段具有執(zhí)行權(quán)限。
SHM_RDONLY附加段以進(jìn)行只讀訪問。進(jìn)程必須具有段的讀取權(quán)限。如果未指定此標(biāo)志,則附加該段以進(jìn)行讀寫訪問,并且進(jìn)程必須具有該段的讀寫權(quán)限。不存在只寫共享內(nèi)存段的概念。
SHM_REMAP(特定于Linux)此標(biāo)志指定線段的映射應(yīng)替換范圍內(nèi)從shmaddr開始并持續(xù)到線段大小的任何現(xiàn)有映射。(通常,如果此地址范圍中已存在映射,則會導(dǎo)致EINVAL錯誤。)在這種情況下,shmaddr不能為空。

呼叫進(jìn)程的brk()值不被附加改變。該段將在進(jìn)程退出時自動分離。同一段可以作為讀寫段附加在進(jìn)程的地址空間中,并且可以多次附加。

成功的shmat()調(diào)用更新與共享內(nèi)存段相關(guān)聯(lián)的shmid_ds結(jié)構(gòu)的成員【參見shmctl()】,如下所示:
shm_ atime被設(shè)置為當(dāng)前時間。

shm_ lpid被設(shè)置為調(diào)用進(jìn)程的進(jìn)程ID。

shm_natch遞增1。

返回值:成功時,shmat()返回附加共享內(nèi)存段的地址;錯誤時,返回(void*)-1,并設(shè)置errno以指示錯誤原因。

錯誤:當(dāng)shmat()失敗時,errno設(shè)置為以下之一:

錯誤代碼含義
EACCES調(diào)用進(jìn)程不具有請求的附加類型所需的權(quán)限,并且不具有CAP_IPC_OWNER功能。
EIDRMshmid指向已刪除的標(biāo)識符。
EINVAL無效的shmid值,未對齊(即,未頁面對齊且未指定SHM_RND)或無效的shmaddr值,或無法在shmaddr處附加段,或指定了SHM_ REMAP且shmaddr為空。
ENOMEM無法為描述符或頁表分配內(nèi)存。

3.3、shmdt()

將共享內(nèi)存從當(dāng)前進(jìn)程中分離。注意,將共享內(nèi)存分離并不是刪除它,只是使該共享內(nèi)存對當(dāng)前進(jìn)程不再可用。函數(shù)原型:

#include <sys/types.h>
#include <sys/shm.h>
int shmdt(const void *shmaddr);

描述:shmdt()將位于shmaddr指定地址的共享內(nèi)存段從調(diào)用進(jìn)程的地址空間中分離。要分離的段當(dāng)前附加的shmaddr必須等于附加的shmat()調(diào)用返回的值。

參數(shù)shmaddr是shmat()函數(shù)返回的地址指針。

在成功調(diào)用shmdt()時,系統(tǒng)更新與共享內(nèi)存段關(guān)聯(lián)的shmid_ds結(jié)構(gòu)的成員,如下所示:
shm_ atime被設(shè)置為當(dāng)前時間。
shm_ lpid被設(shè)置為調(diào)用進(jìn)程的進(jìn)程ID。
shm_natch減1。

返回值:成功時,shmdt()返回0;在出現(xiàn)錯誤時,返回-1,并設(shè)置errno以指示錯誤原因。

錯誤:當(dāng)shmdt()失敗時,errno設(shè)置如下:

錯誤代碼含義
EINVAL在shmaddr沒有附加共享內(nèi)存段;或者,shmaddr不在頁面邊界上對齊。

3.4、shmctl()

控制共享內(nèi)存。函數(shù)原型:

#include <sys/ipc.h>
#include <sys/shm.h>
int shmctl(int shmid, int cmd, struct shmid_ds *buf);

描述:shmctl()對系統(tǒng)V共享內(nèi)存段執(zhí)行cmd指定的控制操作,該段的標(biāo)識符在shmid中給出。
buf參數(shù)是指向shmid_ds結(jié)構(gòu)的指針,如下:

struct shmid_ds {
	   struct ipc_perm shm_perm;    /* Ownership and permissions */
	   size_t          shm_segsz;   /* Size of segment (bytes) */
	   time_t          shm_atime;   /* Last attach time */
	   time_t          shm_dtime;   /* Last detach time */
	   time_t          shm_ctime;   /* Last change time */
	   pid_t           shm_cpid;    /* PID of creator */
	   pid_t           shm_lpid;    /* PID of last shmat(2)/shmdt(2) */
	   shmatt_t        shm_nattch;  /* No. of current attaches */
	   ...
};

ipc_perm結(jié)構(gòu)定義如下:

struct ipc_perm {
    key_t          __key;    /* Key supplied to shmget(2) */
    uid_t          uid;      /* Effective UID of owner */
    gid_t          gid;      /* Effective GID of owner */
    uid_t          cuid;     /* Effective UID of creator */
    gid_t          cgid;     /* Effective GID of creator */
    unsigned short mode;     /* Permissions + SHM_DEST and
                                SHM_LOCKED flags */
    unsigned short __seq;    /* Sequence number */
};

返回值:成功的IPC_INFO或SHM_INFO操作將返回內(nèi)核內(nèi)部數(shù)組中記錄所有共享內(nèi)存段信息的最高使用項的索引。(此信息可與重復(fù)的SHM_STAT操作一起使用,以獲得有關(guān)系統(tǒng)上所有共享內(nèi)存段的信息。)成功的SHM_STAT操作返回其索引在shmid中給出的共享內(nèi)存段標(biāo)識符。其他操作成功時返回0。
出現(xiàn)錯誤時,返回-1,并適當(dāng)設(shè)置errno。

3.5、流程

總結(jié)

共享內(nèi)存,可以大大加快對文件或設(shè)備的讀寫操作。共享內(nèi)存的方式有mmap和shmget 、 shmat。

所謂的零拷貝,就是不需要CPU的參與,而不是其他的意思。

mmap內(nèi)部其實是一個DMA技術(shù)。

以上就是深入學(xué)習(xí)C語言mmap和shm*的使用方法技巧的詳細(xì)內(nèi)容,更多關(guān)于C語言mmap shm*方法的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C語言關(guān)鍵字auto與register及static專項詳解

    C語言關(guān)鍵字auto與register及static專項詳解

    這篇文章主要解釋了c語言中什么是數(shù)據(jù)類型,什么是變量,他們的真正含義是什么。分析了屬性關(guān)鍵字auto,register和static的用法
    2022-07-07
  • 深入理解C語言的new[]和delete[]

    深入理解C語言的new[]和delete[]

    new和delete既是C++中的關(guān)鍵字也是一種特殊的運算符。這篇文章主要介紹了C++的new和delete詳解,需要的朋友可以參考下
    2021-09-09
  • C語言實現(xiàn)客房管理系統(tǒng)

    C語言實現(xiàn)客房管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語言實現(xiàn)客房管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • Qt中QPainter與坐標(biāo)的使用

    Qt中QPainter與坐標(biāo)的使用

    本文主要介紹了Qt中QPainter與坐標(biāo)的使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • C++輸入一個字符串,把其中的字符按照逆序輸出的兩種方法解析

    C++輸入一個字符串,把其中的字符按照逆序輸出的兩種方法解析

    以下是對C++中輸入一個字符串,把其中的字符按照逆序輸出的兩種方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過來參考下
    2013-07-07
  • C++用boost.signal實現(xiàn)多播委托

    C++用boost.signal實現(xiàn)多播委托

    這篇文章介紹了C++用boost.signal實現(xiàn)多播委托的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06
  • C++實現(xiàn)約瑟夫環(huán)的循環(huán)單鏈表

    C++實現(xiàn)約瑟夫環(huán)的循環(huán)單鏈表

    這篇文章主要為大家詳細(xì)介紹了C++實現(xiàn)約瑟夫環(huán)的循環(huán)單鏈表,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • QT線程QThread的使用介紹

    QT線程QThread的使用介紹

    在進(jìn)行桌面應(yīng)用程序開發(fā)的時候,假設(shè)程序在某些情況要處理復(fù)雜邏輯, 如果一個線程去處理,就會導(dǎo)致窗口卡頓,無法處理用戶操作。這就需要使用多線程,其中一個線程處理窗口事件,其他線程進(jìn)行邏輯運算,多個線程各司其職,不僅可以提高用戶體驗還可以提升程序的執(zhí)行效率
    2022-09-09
  • VSCode無法打開源文件及無法打開鏈接庫文件的解決方法

    VSCode無法打開源文件及無法打開鏈接庫文件的解決方法

    本文主要介紹了VSCode無法打開源文件及無法打開鏈接庫文件的解決方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • 基于C語言實現(xiàn)UDP客戶端

    基于C語言實現(xiàn)UDP客戶端

    UDP是一種面向無連接的傳輸層協(xié)議,廣泛應(yīng)用于實時性要求較高的場景,本文將介紹如何使用C語言實現(xiàn)一個簡單的UDP客戶端程序,有需要的可以參考下
    2024-10-10

最新評論

南京市| 清河县| 临高县| 海阳市| 延庆县| 伊金霍洛旗| 加查县| 都安| 伊宁县| 嵊州市| 大余县| 平阳县| 武冈市| 新化县| 交口县| 彰化县| 双江| 祁东县| 榆树市| 明星| 张掖市| 布拖县| 枣强县| 通海县| 溧阳市| 阳朔县| 建德市| 清流县| 文成县| 增城市| 蓬莱市| 安阳市| 开远市| 彰化县| 田林县| 四子王旗| 邵武市| 清水河县| 乐平市| 班玛县| 唐海县|