進(jìn)程間通信

進(jìn)程的讀寫

寫文件的進(jìn)程只能單個(gè)運(yùn)行(寫的時(shí)候禁止讀),讀文件的進(jìn)程可以同時(shí)有多個(gè)贸诚,
讀寫的互斥鎖wsem秧了,rsem
讀寫進(jìn)程的優(yōu)先性同級(jí),讀進(jìn)程有優(yōu)先權(quán)時(shí)(讀的時(shí)候拿走寫鎖)受扳,

進(jìn)程間通信方式

Pipe, fifo, shared memory, mmap, samaphone, socket, mesgq,
有名管道和無(wú)名管道
共享文件
共享內(nèi)存
消息隊(duì)列
內(nèi)存映射
socket監(jiān)聽套接字
信號(hào)量

管道

管道通信詳解
管道為單向, Pipe携龟,上級(jí)進(jìn)程創(chuàng)建,無(wú)名管道通信
pipe, pipe2 - create pipe

   #include <unistd.h>
   int pipe(int pipefd[2]);
   #define _GNU_SOURCE             /* See feature_test_macros(7) */
   #include <fcntl.h>              /* Obtain O_* constant definitions */
   #include <unistd.h>
   int pipe2(int pipefd[2], int flags);
  return -1 為失敗

管道通信函數(shù)例

// ./named-pipe-chat  發(fā)送消息
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>

// 用戶名的最大長(zhǎng)度
#define USER_NAME_MAX_LEN 100
// 發(fā)送消息文本的最大長(zhǎng)度
#define MSG_MAX_LEN 500
// 文件名的最大長(zhǎng)度
#define FILE_NAME_MAX_LEN 100

// 聊天消息結(jié)構(gòu)體類型
struct msg_node 
{
    // 發(fā)送消息用戶名
    char src_username[USER_NAME_MAX_LEN];
    // 接收消息用戶名
    char dst_username[USER_NAME_MAX_LEN];
    // 消息文本
    char text[MSG_MAX_LEN];
};

int main(int argc, char *argv[])
{
    // 判斷命令行參數(shù)是否滿足條件
    if(argc != 2)
    {
        printf("usage : %s <username>\n", argv[0]);
        return 1;
    }

    // 子進(jìn)程ID
    pid_t child_pid;
    // 登陸用戶的命令管道文件名
    char filename[FILE_NAME_MAX_LEN] = {'\0'};

    // 構(gòu)造登陸用命名的管道文件名勘高,并判定用戶是否存在
    sprintf(filename, "%s.fifo", argv[1]);
    if(access(filename, F_OK) != 0)//判斷用戶名文件是否存在峡蟋,存在返回0
    {
        mkfifo(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    }

    // 創(chuàng)建子進(jìn)程
    if((child_pid = fork()) == 0)       // 子進(jìn)程中執(zhí)行的代碼,子進(jìn)程負(fù)責(zé)接收其他用戶發(fā)送的消息并打印顯示
    {
        int n = 0;
        struct msg_node msg;
        int fd = 0;
        
        // 1.打開登陸用戶的管道文件相满,用于接收其他用戶發(fā)送的消息數(shù)據(jù)結(jié)構(gòu)體
        if((fd = open(filename, O_RDONLY)) == -1)
        {
            perror("open failed");
            return 1;
        }
        // 2.循環(huán)的從管道文件中讀入消息信息,并打印顯示
        while( (n = read(fd, &msg, sizeof(msg)) ) > 0)
        {
            printf( "%s ----> %s : %s\n",
            msg.src_username, msg.dst_username, msg.text);
        }
        close(fd);
    }
    else  if(child_pid > 0)          // 父進(jìn)程桦卒,負(fù)責(zé)從鍵盤讀入相關(guān)數(shù)據(jù)立美,寫入執(zhí)行用戶的管道文件
    {
        struct msg_node msg ;
        int fd = 0;
        // 接收用戶的管道文件名
        char dst_filename[FILE_NAME_MAX_LEN] = {'\0'};
                   
        // 發(fā)送者永遠(yuǎn)為當(dāng)前登錄用戶
        strcpy(msg.src_username, argv[1]);
        
            // 1.輸入接收消息的用戶名名稱
            printf("to>");
            fgets(&msg.dst_username, USER_NAME_MAX_LEN, stdin);
            // 1.1將用戶名末尾的'\n'替換為'\0'
            msg.dst_username[strlen(msg.dst_username)-1] = '\0';
            // 1.2構(gòu)造接收用戶的管道文件名
            sprintf(dst_filename, "%s.fifo", msg.dst_username) ;
            // 1.3打開管道文件
            if((fd = open(dst_filename, O_WRONLY)) == -1)
            {
                perror("open failed");
                return 1;
            } 
      // 循環(huán)的發(fā)送從鍵盤讀入的數(shù)據(jù)
        while(1)
        {
            // 2.輸入待發(fā)送的消息字符串
            printf("text>");
            fgets(&msg.text, MSG_MAX_LEN, stdin);
            // 2.2將消息文本末尾的'\n'替換為'\0'
            msg.text[strlen(msg.text)-1] = '\0';
            
            // 3.將構(gòu)造的消息結(jié)構(gòu)體寫入管道文件
                
                
            // 3.2將構(gòu)造的結(jié)構(gòu)體寫入管道文件
            write(fd, &msg, sizeof(msg));
            // 3.3close
        }
       close(fd);
    }
    else
    {
    }
    
    // 刪除登陸用戶的管道文件
    remove(filename);

    return 0;
}

有名管道通信

mkfifo
mkfifo - make a FIFO special file (a named pipe)
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
return 成功返回0,失敗返回1

有名管道--寫信息
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
    int n = 0;
    char buf[1024] = {'\0'};
    int fd = 0;

    // 判斷有名管道文件是否存在方灾,不存在則創(chuàng)建
    if(access("test_file.fifo", F_OK) != 0 )
    {
        mkfifo("test_file.fifo", 
            S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    }
    // 1.打開管道文件
    if((fd = open("test_file.fifo", O_WRONLY)) == -1)
    {
        perror("open failed");
        return 1;
    }

    printf("waiting for input data...\n");
    while(1)
    {
        // 2.從標(biāo)準(zhǔn)輸入文件中讀入數(shù)據(jù)
        n = read(STDIN_FILENO, buf, 1024);
        // 3.將讀到的數(shù)據(jù)寫入到管道文件中
        write(fd, buf, n);
    }
    
    printf("writer process exit...\n");
    
    return 0;
}
有名管道--讀取信息
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>

int main(int argc, char *argv[])
{
    int n = 0;
    char buf[1024] = {'\0'};
    int fd = 0;
    
       
    // 1.打開管道文件
    fd = open("test_file.fifo", O_RDONLY);
    if(fd == -1)
    {
        perror("open failed");
        return 1;
    }
    
    printf("reading for writer data...\n");
    // 2.從管道文件中讀取數(shù)據(jù)
    while((n = read(fd, buf, 1024)) > 0)
    {
        // 3.將讀到的數(shù)據(jù)寫入到標(biāo)準(zhǔn)輸出文件中
        write(STDOUT_FILENO, buf, n);
    }
    
    printf("reader process exit...\n");
    
    return 0;
} 
互斥鎖建蹄,線程間通信的函數(shù)例
#include<stdio.h>
#include<pthread.h>
#include<semaphore.h>
//有限資源的使用中,避免死鎖裕偿。
//哲學(xué)家吃飯問(wèn)題洞慎,有五只筷子,五個(gè)人嘿棘,每人用二只劲腿,不允許沖突。

#define N 5
sem_t kuaizis[N];
sem_t room;

void *phi_thread_func(void *arg);

int main ()
{
    int i =0;
    pthread_t thread_ids[N];
    sem_init(&room,0,4);
    for(i=0;i<N;i++)
    {
        sem_init(&kuaizis[i],0,1);
    }
    for(i=0;i<N;i++)
    {
        pthread_create(&thread_ids[i],NULL,phi_thread_func,(void **)i);
    }
    for(i=0;i<N;i++)
    {
        pthread_join(thread_ids[i],NULL);
    }
    return 0;
}

void *phi_thread_func(void *arg)
{
int thread_no = (int )arg;
sem_wait(&room);
sem_wait (&kuaizis[thread_no]);
sem_wait(&kuaizis[(thread_no+1)%N]);

printf("%d eating\n",thread_no);

sem_post(&kuaizis[(thread_no+1)%N]);
sem_post(&kuaizis[thread_no]);
sem_post(&room);

pthread_exit(NULL);
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末鸟妙,一起剝皮案震驚了整個(gè)濱河市焦人,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌重父,老刑警劉巖花椭,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異房午,居然都是意外死亡矿辽,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)袋倔,“玉大人雕蔽,你說(shuō)我怎么就攤上這事∞任郏” “怎么了萎羔?”我有些...
    開封第一講書人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)碳默。 經(jīng)常有香客問(wèn)我贾陷,道長(zhǎng),這世上最難降的妖魔是什么嘱根? 我笑而不...
    開封第一講書人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任髓废,我火速辦了婚禮,結(jié)果婚禮上该抒,老公的妹妹穿的比我還像新娘慌洪。我一直安慰自己,他們只是感情好凑保,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開白布冈爹。 她就那樣靜靜地躺著,像睡著了一般欧引。 火紅的嫁衣襯著肌膚如雪频伤。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,111評(píng)論 1 285
  • 那天芝此,我揣著相機(jī)與錄音憋肖,去河邊找鬼。 笑死婚苹,一個(gè)胖子當(dāng)著我的面吹牛岸更,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播膊升,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼怎炊,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了廓译?” 一聲冷哼從身側(cè)響起结胀,我...
    開封第一講書人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎责循,沒(méi)想到半個(gè)月后糟港,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡院仿,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年秸抚,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了速和。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡剥汤,死狀恐怖颠放,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情吭敢,我是刑警寧澤碰凶,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布,位于F島的核電站鹿驼,受9級(jí)特大地震影響欲低,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜畜晰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一砾莱、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧凄鼻,春花似錦腊瑟、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至峭范,卻和暖如春财松,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背虎敦。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工游岳, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留政敢,地道東北人其徙。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像喷户,于是被迫代替她去往敵國(guó)和親唾那。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容