国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

linux|進程間通信如何加鎖

這篇具有很好參考價值的文章主要介紹了linux|進程間通信如何加鎖。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

進程間通信有一種[共享內(nèi)存]方式,大家有沒有想過,這種通信方式中如何解決數(shù)據(jù)競爭問題?我們可能自然而然的就會想到用鎖。但我們平時使用的鎖都是用于解決線程間數(shù)據(jù)競爭問題,貌似沒有看到過它用在進程中,那怎么辦?

linux|進程間通信如何加鎖

?關(guān)于進程間的通信方式估計大多數(shù)人都知道,這也是常見的面試八股文之一。

個人認為這種面試題沒什么意義,無非就是答幾個關(guān)鍵詞而已,更深入的可能面試官和面試者都不太了解。

關(guān)于進程間通信方式我之前在這前的文章中有過介紹,感興趣的可以移步去看哈。

進程間通信有一種[共享內(nèi)存]方式,大家有沒有想過,這種通信方式中如何解決數(shù)據(jù)競爭問題?

我們可能自然而然的就會想到用鎖。但我們平時使用的鎖都是用于解決線程間數(shù)據(jù)競爭問題,貌似沒有看到過它用在進程中,那怎么辦?

我找到了兩種方法,信號量和互斥鎖。

直接給大家貼代碼吧,首先是信號量方式:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

constexpr int kMappingSize = 4096;

void sem() {
    const char* mapname = "/mapname";
    int mapfd = shm_open(mapname, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);

    MEOW_DEFER {
        if (mapfd > 0) {
            close(mapfd);
            mapfd = 0;
        }
        shm_unlink(mapname);
    };

    if (mapfd == -1) {
        perror("shm_open failed \n");
        exit(EXIT_FAILURE);
    }

    if (ftruncate(mapfd, kMappingSize) == -1) {
        perror("ftruncate failed \n");
        exit(EXIT_FAILURE);
    }

    void* sp = mmap(nullptr, kMappingSize, PROT_READ | PROT_WRITE, MAP_SHARED, mapfd, 0);
    if (!sp) {
        perror("mmap failed \n");
        exit(EXIT_FAILURE);
    }

    sem_t* mutex = (sem_t*)sp;

    if (sem_init(mutex, 1, 1) != 0) {
        perror("sem_init failed \n");
        exit(EXIT_FAILURE);
    }

    MEOW_DEFER { sem_destroy(mutex); };

    int* num = (int*)((char*)sp + sizeof(sem_t));
    int cid, proc_count = 0, max_proc_count = 8;
    for (int i = 0; i < max_proc_count; ++i) {
        cid = fork();
        if (cid == -1) {
            perror("fork failed \n");
            continue;
        }
        if (cid == 0) {
            sem_wait(mutex);
            (*num)++;
            printf("process %d : %d \n", getpid(), *num);
            sem_post(mutex);

            if (munmap(sp, kMappingSize) == -1) {
                perror("munmap failed\n");
            }
            close(mapfd);
            exit(EXIT_SUCCESS);
        }
        ++proc_count;
    }

    int stat;
    while (proc_count--) {
        cid = wait(&stat);
        if (cid == -1) {
            perror("wait failed \n");
            break;
        }
    }

    printf("ok \n");
}

代碼中的MEOW_DEFER,它內(nèi)部的函數(shù)會在生命周期結(jié)束后觸發(fā)。它的核心函數(shù)其實就是下面這四個:

int sem_init(sem_t *sem,int pshared,unsigned int value);
int sem_post(sem_t *sem);
int sem_wait(sem_t *sem);
int sem_destroy(sem_t *sem);

具體含義大家應(yīng)該看名字就知道,這里的重點就是sem_init中的pshared參數(shù),該參數(shù)為1表示可在進程間共享,為0表示只在進程內(nèi)部共享。

第二種方式是使用鎖,即pthread_mutex_t,可是pthread_mutex不是用作線程間數(shù)據(jù)競爭的嗎,怎么能用在進程間呢?

可以給它配置一個屬性,示例代碼如下:

pthread_mutex_t* mutex;
pthread_mutexattr_t mutexattr;

pthread_mutexattr_init(&mutexattr);
pthread_mutexattr_setpshared(&mutexattr, PTHREAD_PROCESS_SHARED);
pthread_mutex_init(mutex, &mutexattr);

它的默認屬性是進程內(nèi)私有,但是如果給它配置成PTHREAD_PROCESS_SHARED,它就可以用在進程間通信中。

相關(guān)視頻推薦

360度無死角講解進程管理,調(diào)度器的5種實現(xiàn)

初識linux內(nèi)核,進程通信還能這么玩

免費學(xué)習(xí)地址:C/C++Linux服務(wù)器開發(fā)/后臺架構(gòu)師

需要C/C++ Linux服務(wù)器架構(gòu)師學(xué)習(xí)資料加qun579733396獲?。ㄙY料包括C/C++,Linux,golang技術(shù),Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒體,CDN,P2P,K8S,Docker,TCP/IP,協(xié)程,DPDK,ffmpeg等),免費分享

linux|進程間通信如何加鎖

?

完整代碼如下:

void func() {
    const char* mapname = "/mapname";
    int mapfd = shm_open(mapname, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);

    MEOW_DEFER {
        if (mapfd > 0) {
            close(mapfd);
            mapfd = 0;
        }
        shm_unlink(mapname);
    };

    if (mapfd == -1) {
        perror("shm_open failed \n");
        exit(EXIT_FAILURE);
    }

    if (ftruncate(mapfd, kMappingSize) == -1) {
        perror("ftruncate failed \n");
        exit(EXIT_FAILURE);
    }

    void* sp = mmap(nullptr, kMappingSize, PROT_READ | PROT_WRITE, MAP_SHARED, mapfd, 0);
    if (!sp) {
        perror("mmap failed \n");
        exit(EXIT_FAILURE);
    }

    pthread_mutex_t* mutex = (pthread_mutex_t*)sp;
    pthread_mutexattr_t mutexattr;

    pthread_mutexattr_init(&mutexattr);
    pthread_mutexattr_setpshared(&mutexattr, PTHREAD_PROCESS_SHARED);
    pthread_mutex_init(mutex, &mutexattr);

    MEOW_DEFER {
        pthread_mutexattr_destroy(&mutexattr);
        pthread_mutex_destroy(mutex);
    };

    int* num = (int*)((char*)sp + sizeof(pthread_mutex_t));
    int cid, proc_count = 0, max_proc_count = 8;
    for (int i = 0; i < max_proc_count; ++i) {
        cid = fork();
        if (cid == -1) {
            perror("fork failed \n");
            continue;
        }
        if (cid == 0) {
            pthread_mutex_lock(mutex);
            (*num)++;
            printf("process %d : %d \n", getpid(), *num);
            pthread_mutex_unlock(mutex);

            if (munmap(sp, kMappingSize) == -1) {
                perror("munmap failed\n");
            }
            close(mapfd);
            exit(EXIT_SUCCESS);
        }
        ++proc_count;
    }

    int stat;
    while (proc_count--) {
        cid = wait(&stat);
        if (cid == -1) {
            perror("wait failed \n");
            break;
        }
    }

    printf("ok \n");
}

我想這兩種方式應(yīng)該可以滿足我們?nèi)粘i_發(fā)過程中的大多數(shù)需求。

鎖的方式介紹完之后,可能很多朋友自然就會想到原子變量,這塊我也搜索了一下。但是也不太確定C++標(biāo)準(zhǔn)中的atomic是否在進程間通信中有作用,不過看樣子boost中的atomic是可以用在進程間通信中的。

其實在研究這個問題的過程中,還找到了一些很多解決辦法,包括:

Disabling Interrupts

Lock Variables

Strict Alternation

Peterson's Solution

The TSL Instruction

Sleep and Wakeup

Semaphores

Mutexes

Monitors

Message Passing

Barriers

這里就不過多介紹啦,大家感興趣的可以自行查閱資料哈。文章來源地址http://www.zghlxwxcb.cn/news/detail-431947.html

到了這里,關(guān)于linux|進程間通信如何加鎖的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【Linux】進程通信之匿名管道通信

    【Linux】進程通信之匿名管道通信

    我們往往需要多個進程協(xié)同,共同完成一些事情。 數(shù)據(jù)傳輸:一個進程需要將它的數(shù)據(jù)發(fā)送給另一個進程 資源共享:多個進程之間共享同樣的資源。 通知事件:一個進程需要向另一個或一組進程發(fā)送消息,通知它(它們)發(fā)生了某種事件(如進程終止 時要通知父進程)。

    2024年04月14日
    瀏覽(24)
  • Linux--進程間的通信--進程池

    Linux--進程間的通信--進程池

    進程間的通信–匿名管道 進程池是一種將多個進程組織起來以執(zhí)行特定任務(wù)的機制 。 它由多個預(yù)先創(chuàng)建好的資源進程和一個管理進程組成。這些資源進程被管理進程負責(zé)分配和調(diào)度,用于處理任務(wù) 。 當(dāng)有新的任務(wù)提交時,管理進程會從進程池中取出一個資源進程,將任務(wù)

    2024年04月25日
    瀏覽(31)
  • Linux多進程(二)進程通信方式一 管道

    Linux多進程(二)進程通信方式一 管道

    管道的是進程間通信(IPC - InterProcess Communication)的一種方式,管道的本質(zhì)其實就是內(nèi)核中的一塊內(nèi)存(或者叫內(nèi)核緩沖區(qū)),這塊緩沖區(qū)中的數(shù)據(jù)存儲在一個環(huán)形隊列中,因為管道在內(nèi)核里邊,因此我們不能直接對其進行任何操作。 因為管道數(shù)據(jù)是通過隊列來維護的,我們先

    2024年04月29日
    瀏覽(16)
  • 【Linux】Linux進程間通信(三)

    【Linux】Linux進程間通信(三)

    ? ???個人主頁:@Sherry的成長之路 ??學(xué)習(xí)社區(qū):Sherry的成長之路(個人社區(qū)) ??專欄鏈接:Linux ?? 長路漫漫浩浩,萬事皆有期待 上一篇博客:【Linux】Linux進程概念 管道通信本質(zhì)是基于文件的,也就是說操作系統(tǒng)并沒有為此做過多的設(shè)計工作,而system V IPC是操作系統(tǒng)特

    2024年02月05日
    瀏覽(16)
  • 【Linux C | 進程】Linux 進程間通信的10種方式(2)

    【Linux C | 進程】Linux 進程間通信的10種方式(2)

    ??博客主頁??:??https://blog.csdn.net/wkd_007?? ??博客內(nèi)容??:??嵌入式開發(fā)、Linux、C語言、C++、數(shù)據(jù)結(jié)構(gòu)、音視頻?? ??本文內(nèi)容??:??介紹 ?? ??金句分享??:??你不能選擇最好的,但最好的會來選擇你——泰戈爾?? 本文未經(jīng)允許,不得轉(zhuǎn)發(fā)?。?! POSIX消息隊列與

    2024年02月20日
    瀏覽(14)
  • 【Linux C | 進程】Linux 進程間通信的10種方式(1)

    【Linux C | 進程】Linux 進程間通信的10種方式(1)

    ??博客主頁??:??https://blog.csdn.net/wkd_007?? ??博客內(nèi)容??:??嵌入式開發(fā)、Linux、C語言、C++、數(shù)據(jù)結(jié)構(gòu)、音視頻?? ??本文內(nèi)容??:??介紹 ?? ??金句分享??:??你不能選擇最好的,但最好的會來選擇你——泰戈爾?? 本文未經(jīng)允許,不得轉(zhuǎn)發(fā)?。?! 下表是進程間通

    2024年01月25日
    瀏覽(15)
  • Linux——進程間通信、管道

    Linux——進程間通信、管道

    進程間的通信就是 在不同進程之間傳播或交換信息。 舉個例子: 古時,兩軍交戰(zhàn)不斬來使; 因為兩軍互相是獨立的,所以使節(jié)就是兩軍之間傳話的進行傳話的; 而在OS中,進程之間也是相互獨立的,但某項工作并不是一個進程就可以完成,而是多個進程之間相互協(xié)助完成;

    2024年02月22日
    瀏覽(23)
  • Linux系統(tǒng)-進程間通信

    Linux系統(tǒng)-進程間通信

    本章主要講解學(xué)習(xí)Linux中本系統(tǒng)下的進程間通信 概念: 進程間通信簡稱IPC(Inter process communication),進程間通信就是在不同進程之間傳播或交換信息 進程間通信目的: 數(shù)據(jù)傳輸:一個進程需要將它的數(shù)據(jù)發(fā)送給另一個進程 資源共享:多個進程之間共享同樣的資源 通知事件

    2024年02月05日
    瀏覽(19)
  • linux——進程間通信——管道

    linux——進程間通信——管道

    ??1主頁::我的代碼愛吃辣 ??2知識講解:Linux——進程間通信——管道通信 ??3開發(fā)環(huán)境:Centos7 ??4前言:進程間通信(InterProcess Communication,IPC)是指在不同進程之間傳播或交換信息。 目錄 一.什么是進程間通信 二.進程間通信目的 ?三.進程間通信發(fā)展 四.什么是管道

    2024年02月08日
    瀏覽(40)
  • Linux——進程間通信&&管道

    Linux——進程間通信&&管道

    ??北塵_ :個人主頁 ??個人專欄 :《Linux操作系統(tǒng)》《經(jīng)典算法試題 》《C++》 《數(shù)據(jù)結(jié)構(gòu)與算法》 ??走在路上,不忘來時的初心 數(shù)據(jù)傳輸:一個進程需要把他的數(shù)據(jù)傳給另外一個進程。 資源共享:多個進程之間共享同樣的資源。 通知事件:一個進程需要向另一個或一組

    2024年04月09日
    瀏覽(27)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包