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

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

這篇具有很好參考價(jià)值的文章主要介紹了【Linux C | 進(jìn)程】Linux 進(jìn)程間通信的10種方式(1)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

??博客主頁(yè)??:??https://blog.csdn.net/wkd_007??
??博客內(nèi)容??:??嵌入式開發(fā)、Linux、C語(yǔ)言、C++、數(shù)據(jù)結(jié)構(gòu)、音視頻??
??本文內(nèi)容??:??介紹 ??
??金句分享??:??你不能選擇最好的,但最好的會(huì)來(lái)選擇你——泰戈?duì)??

本文未經(jīng)允許,不得轉(zhuǎn)發(fā)?。。?/font>


【Linux C | 進(jìn)程】Linux 進(jìn)程間通信的10種方式(1),# ?Linux C語(yǔ)言,linux,Linux進(jìn)程間通信,管道,消息隊(duì)列,信號(hào)量,共享內(nèi)存
下表是進(jìn)程間通信的十種方式

??一、管道(無(wú)名管道)

?1.1 管道介紹

管道是半雙工的通信方式,數(shù)據(jù)只能單向流動(dòng),管道的作用是在有親緣關(guān)系的進(jìn)程之間傳遞消息。所謂親緣關(guān)系是指,只要調(diào)用進(jìn)程使用pipe函數(shù), 打開的管道文件就會(huì)在fork之后, 被各個(gè)后代進(jìn)程所共享。

這個(gè)無(wú)名管道可以理解為:沒(méi)有實(shí)體文件與之關(guān)聯(lián), 靠的是世代相傳的文件描述符來(lái)進(jìn)行數(shù)據(jù)的讀寫。

無(wú)名管道可以使用函數(shù)pipe來(lái)創(chuàng)建,函數(shù)原型如下:

#include <unistd.h>
int pipe(int pipefd[2]);

?1.2 例子

看使用例子,父進(jìn)程調(diào)用了pipe函數(shù)創(chuàng)建了管道文件,fork之后的子進(jìn)程可以直接使用管道文件:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>  

#define PIPE_INPUT		0
#define PIPE_OUTPUT		1

int main()
{
	int pipe_fds[2];
	pipe(pipe_fds); // 創(chuàng)建無(wú)名管道
	
	pid_t pid = fork();
    if(pid == 0) {// 子進(jìn)程
		printf("子進(jìn)程[%d]開始執(zhí)行, 關(guān)閉輸入管道,寫數(shù)據(jù)到輸出管道\n", getpid()); 
		close(pipe_fds[PIPE_INPUT]);// 關(guān)閉輸入管道
		write(pipe_fds[PIPE_OUTPUT], "test data", strlen("test data"));// 寫入管道
        exit(0);
    }
	else if(pid > 0)
	{
		sleep(2); //延時(shí)一會(huì),讓子進(jìn)程先運(yùn)行
		printf("父進(jìn)程[%d]開始執(zhí)行, 關(guān)閉輸出管道,讀取管道數(shù)據(jù)\n", getpid()); 
		close(pipe_fds[PIPE_OUTPUT]);// 關(guān)閉輸出管道
		char buf[256] = {0,};
		int readSize = read(pipe_fds[PIPE_INPUT], buf, sizeof(buf));
		printf("父進(jìn)程[%d]從管道讀取到%d個(gè)字節(jié)的數(shù)據(jù)[%s]\n", getpid(), readSize, buf); 
        exit(0);
	}
	else
	{
		printf("Error in fork\n"); 
        exit(1); 
	}
	
	return 0;
}

在這里插入圖片描述

??二、命名管道FIFO

?2.1 命名管道FIFO介紹

上面的無(wú)名管道沒(méi)有與實(shí)體文件關(guān)聯(lián),靠的是世代相傳的文件描述符來(lái)進(jìn)行數(shù)據(jù)交換。命名管道就是為了解決無(wú)名管道的這個(gè)問(wèn)題而引入的。 FIFO與管道類似, 最大的差別就是有實(shí)體文件與之關(guān)聯(lián)。 由于存在實(shí)體文件, 不相關(guān)的、沒(méi)有親緣關(guān)系的進(jìn)程也可以通過(guò)使用FIFO來(lái)實(shí)現(xiàn)進(jìn)程之間的通信。

創(chuàng)建命名管道的3種方式:

  • 1、調(diào)用C語(yǔ)言接口函數(shù)mkfifo創(chuàng)建:mkfifo("my_fifo", 0666);;
    #include <sys/types.h>
    #include <sys/stat.h>
    int mkfifo(const char *pathname, mode_t mode);
    
  • 2、使用mkfifo命令創(chuàng)建:mkfifo -m 0666 my_fifo;
  • 3、使用mknod命令創(chuàng)建:mknod -m 0666 my_fifo p。

一旦FIFO文件創(chuàng)建好了, 就可以把它用于進(jìn)程間的通信了。 一般的文件操作函數(shù)如open、 read、 write、 close、 unlink等都可以用在FIFO文件上。

?2.2 例子

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
	if(0 == access("./my_fifo",F_OK))
	{
		system("rm ./my_fifo");
	}
	/*創(chuàng)建管道文件, 下次運(yùn)行需要先刪除my_fifo文件,否則mkfifo報(bào)錯(cuò)*/
    if(mkfifo("my_fifo", 0666) < 0)
    {
        perror("mkfifo");
        return -1;
    }
	
	pid_t pid = fork();
    if(pid == 0) {// 子進(jìn)程
		printf("子進(jìn)程[%d]開始執(zhí)行, 打開my_fifo文件,循環(huán)往里寫數(shù)據(jù)\n", getpid());
		int fd = open("my_fifo", O_WRONLY);
		if(fd < 0)
		{
			return -1;
		}
		int i = 9;
		while(i>=0)
		{
			printf("子進(jìn)程[%d]寫入數(shù)據(jù):%d\n", getpid(), i);
			char buf[256] = {0,};
			sprintf(buf,"%d",i);
			write(fd, buf, strlen(buf));
			i--;
			sleep(1);
		}
		close(fd);
		printf("子進(jìn)程[%d]退出\n", getpid());
        return 0;
    }
	else if(pid > 0)// 父進(jìn)程
	{
		sleep(5); //延時(shí)一會(huì),讓子進(jìn)程先運(yùn)行
		printf("父進(jìn)程[%d]開始執(zhí)行, 打開my_fifo文件,讀取數(shù)據(jù)\n", getpid()); 
		int fd = open("my_fifo", O_RDONLY);
		if(fd < 0)
		{
			return -1;
		}
		char buf[256] = {0,};
		int readSize = 0;
		while((readSize = read(fd, buf, sizeof(buf)) ) > 0)
		{
			printf("父進(jìn)程[%d]讀取到%d個(gè)字節(jié)數(shù)據(jù):[%s]\n", getpid(),readSize, buf);
			memset(buf, 0, sizeof(buf));
		}
		close(fd);
		printf("父進(jìn)程[%d]退出\n", getpid());
        return 0;
	}
	else
	{
		printf("Error in fork\n"); 
        exit(1); 
	}
	
	return 0;
}

運(yùn)行結(jié)果:
在這里插入圖片描述

在這里插入圖片描述

??三、消息隊(duì)列(System V IPC)

?3.1 消息隊(duì)列(System V IPC)介紹

有三種被稱為XSI IPC的進(jìn)程間通信,消息隊(duì)列,信號(hào)量,共享內(nèi)存。XSI IPC函數(shù)是基于System V的IPC函數(shù)。這里介紹的消息隊(duì)列就屬于其中一種,后面還有介紹其余兩種,消息隊(duì)列比較少用了,是一種逐漸被淘汰的通信方式,為了完整性,這里還是介紹一下,感興趣的可以繼續(xù)了解。

前面的管道通信,如果從管道中讀取到100個(gè)字節(jié),你無(wú)法確認(rèn)這100個(gè)字節(jié)是單次寫入的100字節(jié), 還是分10次每次10字節(jié)寫入的, 你也無(wú)法知曉這100個(gè)字節(jié)是幾個(gè)消息。System V消息隊(duì)列就不存在這種問(wèn)題,因?yàn)樗腔谙⑼ㄐ诺?。無(wú)需從字節(jié)流解析完整的消息,而且每個(gè)消息有type字段作為消息類型。

消息隊(duì)列編程步驟:

  • 1、生成 key,System V IPC的標(biāo)識(shí)ID都是通過(guò)key來(lái)獲取的,key的生成方式有三種:
    ①隨機(jī)選擇一個(gè)整數(shù)值作為key值,這個(gè)值必須不和其他key重復(fù),例如:#define MSG_KEY 10086
    ②使用IPC_PRIVATE,例如:id = msgget(IPC_PRIVATE,S_IRUSR | S_IWUSR);
    ③使用ftok函數(shù), 根據(jù)文件名生成一個(gè)key,例如:key_t key = ftok(".", 100);
  • 2、使用msgget()創(chuàng)建/獲取消息隊(duì)列,返回值為隊(duì)列標(biāo)識(shí)符。
    服務(wù)端創(chuàng)建:int msgid = msgget(key, 0666|IPC_CREAT);
    客戶端獲?。?code>int msgid = msgget(key, 0);
  • 3、寫入/取出消息;
    服務(wù)端寫入:msgsnd(msgid, &msg, sizeof(msg.buf), 0);
    客戶端獲?。?code>msgrcv(msgid, &msg, sizeof(msg)-sizeof(long), 0, 0);
  • 4、msgctl刪除消息隊(duì)列
    msgctl(msgid, IPC_RMID, NULL);

?3.2 例子

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

typedef struct _MSG_TYPE
{
    long mtype;//消息類型
    char buf[256];//有效數(shù)據(jù)
}MSG_TYPE;

int main()
{
	// 1 生成key
    key_t key = ftok(".", 100);

	// 2 創(chuàng)建子進(jìn)程
	pid_t pid = fork();
    if(pid == 0) {// 子進(jìn)程
		printf("子進(jìn)程[%d]開始執(zhí)行, 創(chuàng)建消息隊(duì)列,循環(huán)往里寫數(shù)據(jù)\n", getpid());
		// 創(chuàng)建消息隊(duì)列
		int msgid = msgget(key, 0666|IPC_CREAT);
		if(msgid == -1)
		{
			perror("msgget failed");
			exit(1);
		}
		// 發(fā)送數(shù)據(jù)
		int i = 9;
		MSG_TYPE msg;
		while(i>=0)
		{
			memset(&msg, 0, sizeof(msg));
			msg.mtype = i;
			sprintf(msg.buf, "hello-%d", i);
			msgsnd(msgid, &msg, sizeof(msg.buf), 0);//阻塞
			printf("子進(jìn)程[%d]寫入數(shù)據(jù):hello-%d\n", getpid(), i);
			i--;
			sleep(1);
		}
		
		// 刪除隊(duì)列
		if(msgctl(msgid, IPC_RMID, NULL) == -1)
		{
			perror("msgctl failed");
			exit(3);
		}
		printf("子進(jìn)程[%d]退出\n", getpid());
        return 0;
    }
	else if(pid > 0)// 父進(jìn)程
	{
		sleep(3); //延時(shí)一會(huì),讓子進(jìn)程先運(yùn)行
		printf("父進(jìn)程[%d]開始執(zhí)行, 獲取消息隊(duì)列,讀取數(shù)據(jù)\n", getpid()); 
		int msgid = msgget(key, 0); 
		if(msgid == -1)
		{
			perror("msgget failed");
			exit(1);
		}
		MSG_TYPE msg;
		while(1)
		{
			memset(&msg, 0, sizeof(msg));
			int res = msgrcv(msgid, &msg, sizeof(msg)-sizeof(long), 0, 0);//阻塞
			printf("res=%d, 消息:%s, 類型:%ld\n", res, msg.buf, msg.mtype);
			if(res == -1)
			{
				perror("msgrcv failed");
				break;
			}
		}
		
		// 刪除隊(duì)列
		if(msgctl(msgid, IPC_RMID, NULL) == -1)
		{
			perror("msgctl failed");
			exit(3);
		}
		printf("父進(jìn)程[%d]退出\n", getpid());
        return 0;
	}
	else
	{
		printf("Error in fork\n"); 
        exit(1); 
	}
	
	return 0;
}

運(yùn)行結(jié)果:
在這里插入圖片描述

在這里插入圖片描述

??四、信號(hào)量(System V IPC)

?4.1 消息隊(duì)列(System V IPC)介紹

信號(hào)量的作用是為了同步多個(gè)進(jìn)程的操作。一般來(lái)說(shuō), 信號(hào)量是和某種預(yù)先定義的資源相關(guān)聯(lián)的。

信號(hào)量是一個(gè)計(jì)數(shù)器,控制訪問(wèn)共享資源的最大并行進(jìn)程總數(shù)??梢酝ㄟ^(guò)下面這個(gè)故事來(lái)了解信號(hào)量。

一套豪宅里有8個(gè)一模一樣的衛(wèi)生間和8把通用的鑰匙。最初有8把鑰匙放在鑰匙存放處。 當(dāng)同時(shí)使用衛(wèi)生間的人數(shù)小于或等于8時(shí), 大家都可以拿到一把鑰匙, 各自使用各自的衛(wèi)生間。 但是到第9個(gè)人和第10個(gè)人要使用衛(wèi)生間時(shí), 發(fā)現(xiàn)已經(jīng)沒(méi)有鑰匙了, 所以他們就不得不等待了。

使用最廣泛的信號(hào)量是二值信號(hào)量(binary semaphore), 對(duì)于這種信號(hào)量而言, 它只有兩種合法值: 0和1, 對(duì)應(yīng)一個(gè)可用的資源。 若當(dāng)前有資源可用, 則與之對(duì)應(yīng)的二值信號(hào)量的值為1; 若資源已被占用, 則與之對(duì)應(yīng)的二值信號(hào)量的值為0。 當(dāng)進(jìn)程申請(qǐng)資源時(shí), 如果當(dāng)前信號(hào)量的值為0, 那么進(jìn)程會(huì)陷入阻塞, 直到有其他進(jìn)程釋放資源, 將信號(hào)量的值加1才能被喚醒。

資源個(gè)數(shù)超過(guò)1個(gè)的信號(hào)量稱為計(jì)數(shù)信號(hào)量(counting semaphore),例如,有個(gè)8個(gè)資源,最大同時(shí)允許8個(gè)進(jìn)程使用。

信號(hào)量編程步驟:

  • 1、生成 key,System V IPC的標(biāo)識(shí)ID都是通過(guò)key來(lái)獲取的,key的生成方式有三種。參考上一節(jié)消息隊(duì)列編程步驟;
  • 2、使用int semget(key_t key, int nsems, int semflg);創(chuàng)建/獲取信號(hào)量集,返回值為信號(hào)量集標(biāo)識(shí)符。
    第二個(gè)參數(shù)nsems表示信號(hào)量集中信號(hào)量的個(gè)數(shù)。如果并非創(chuàng)建信號(hào)量, 僅僅是訪問(wèn)已經(jīng)存在的信號(hào)量集, 可以將nsems指定為0。
    semflg支持多種標(biāo)志位。 目前支持IPC_CREAT和IPC_EXCL標(biāo)志位
  • 3、設(shè)置信號(hào)量的初始值 int semctl(int semid, int semnum, int cmd,/* union semun arg*/);
  • 4、正常使用,實(shí)現(xiàn)信號(hào)量的++ --的原子性int semop(int semid, struct sembuf *sops, unsigned nsops);
  • 5、semctl刪除消息信號(hào)量
    semctl(semid, 0, IPC_RMID);

?4.2 例子

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

// 生成key
#define SEM_KEY		10086

int main()
{
	// 2 創(chuàng)建子進(jìn)程
	pid_t pid = fork();
    if(pid == 0) {// 子進(jìn)程
		printf("子進(jìn)程[%d]開始執(zhí)行, 創(chuàng)建信號(hào)量,使用資源\n", getpid());
		// 創(chuàng)建信號(hào)量集
		int semid = semget(SEM_KEY, 1, IPC_CREAT|0666);
		if(semid == -1)
		{
			perror("semget failed");
			exit(1);
		}
		
		// 設(shè)置第0個(gè)信號(hào)量的資源數(shù)量為1
		if(semctl(semid, 0, SETVAL, 1) == -1)
		{
			perror("semctl setval failed");
			exit(1);
		}
		
		// 使用資源,數(shù)量 -1
		struct sembuf op;
		op.sem_num = 0;//對(duì)下標(biāo)為0的信號(hào)量操作
		op.sem_op = -1;//對(duì)信號(hào)量-1
		op.sem_flg = 0;//無(wú)法完成時(shí)阻塞等待
		semop(semid, &op, 1);
		printf("子進(jìn)程[%d]訪問(wèn)共享資源\n", getpid());
		sleep(20);
		printf("子進(jìn)程[%d]完成共享資源的訪問(wèn)\n",getpid());
		
		// 釋放資源,數(shù)量 +1
		op.sem_op = 1;
		semop(semid, &op, 1);
		
        return 0;
    }
	else if(pid > 0)// 父進(jìn)程
	{
		sleep(3); //延時(shí)一會(huì),讓子進(jìn)程先運(yùn)行
		printf("父進(jìn)程[%d]開始執(zhí)行, 獲取信號(hào)量,準(zhǔn)備使用資源\n", getpid()); 
		int semid = semget(SEM_KEY, 0, 0);
		if(semid == -1)
		{
			perror("semget failed");
			exit(1);
		}
		
		// 使用資源,數(shù)量 -1
		struct sembuf op;
		op.sem_num = 0;//對(duì)下標(biāo)為0的信號(hào)量操作
		op.sem_op = -1;//對(duì)信號(hào)量-1
		op.sem_flg = 0;//無(wú)法完成時(shí)阻塞等待
		semop(semid, &op, 1);
		printf("父進(jìn)程[%d]訪問(wèn)共享資源\n", getpid());
		sleep(3);
		printf("父進(jìn)程[%d]完成共享資源的訪問(wèn)\n",getpid());
		
		// 釋放資源,數(shù)量 +1
		op.sem_op = 1;
		semop(semid, &op, 1);
		
		// 刪除信號(hào)量
		if(semctl(semid, 0, IPC_RMID) == -1)
		{
			perror("semctl failed");
			exit(3);
		}
		printf("父進(jìn)程[%d]退出\n", getpid());
        return 0;
	}
	else
	{
		printf("Error in fork\n"); 
        exit(1); 
	}
	
	return 0;
}

在這里插入圖片描述

??五、共享內(nèi)存(System V IPC)

?5.1 共享內(nèi)存(System V IPC)介紹

共享內(nèi)存是所有IPC手段中最快的一種。 它之所以快是因?yàn)楣蚕韮?nèi)存一旦映射到進(jìn)程的地址空間,進(jìn)程之間數(shù)據(jù)的傳遞就不須要涉及內(nèi)核了。

建立共享內(nèi)存之后, 進(jìn)程從此就像操作普通進(jìn)程的地址空間一樣操作這塊共享內(nèi)存, 一個(gè)進(jìn)程可以將信息寫入這片內(nèi)存區(qū)域, 而另一個(gè)進(jìn)程也可以看到共享內(nèi)存里面的信息, 從而達(dá)到通信的目的。

允許多個(gè)進(jìn)程同時(shí)操作共享內(nèi)存, 就不得不防范競(jìng)爭(zhēng)條件的出現(xiàn)。因此, 共享內(nèi)存這種進(jìn)程間通信的手段通常不會(huì)單獨(dú)出現(xiàn), 總是和信號(hào)量、 文件鎖等同步的手段配合使用。

信號(hào)量編程步驟:

  • 1、生成 key,System V IPC的標(biāo)識(shí)ID都是通過(guò)key來(lái)獲取的,key的生成方式有三種。參考上一節(jié)消息隊(duì)列編程步驟;
  • 2、使用int shmget(key_t key, size_t size, int shmflg);創(chuàng)建/獲取共享內(nèi)存段,返回值為共享內(nèi)存的標(biāo)識(shí)符。
    其中第二個(gè)參數(shù)size必須是正整數(shù), 表示要?jiǎng)?chuàng)建的共享內(nèi)存的大小。
    第三個(gè)參數(shù)支持IPC_CREAT和IPC_EXCL標(biāo)志位。 如果沒(méi)有設(shè)置IPC_CREAT標(biāo)志位, 那么第二個(gè)參數(shù)size對(duì)共享內(nèi)存段并無(wú)實(shí)際意義, 但是必須小于或等于共享內(nèi)存的大小, 否則會(huì)有EINVAL錯(cuò)誤。
  • 3、映射共享內(nèi)存,得到虛擬地址。void *shmat(int shmid, const void *shmaddr, int shmflg);。
    其中, 第二個(gè)參數(shù)是用來(lái)指定將共享內(nèi)存放到虛擬地址空間的什么位置的。 大部分的普通青年都會(huì)將第二個(gè)參數(shù)設(shè)置為NULL, 表示用戶并不在意, 一切交由內(nèi)核做主。
    shmat如果調(diào)用成功, 則返回進(jìn)程虛擬地址空間內(nèi)的一個(gè)地址。就可以像使用malloc分配的空間一樣使用共享內(nèi)存。
  • 4、讀寫共享內(nèi)存數(shù)據(jù)。
  • 5、解除映射。int shmdt(const void *shmaddr);。
  • 6、銷毀共享內(nèi)存。shmctl(shmid, IPC_RMID, NULL) ;

?5.2 例子

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

// 生成key
#define SHM_KEY		10010

int main()
{
	// 2 創(chuàng)建子進(jìn)程
	pid_t pid = fork();
    if(pid == 0) {// 子進(jìn)程
		printf("子進(jìn)程[%d]開始執(zhí)行, 創(chuàng)建共享內(nèi)存段,使用創(chuàng)建共享內(nèi)存\n", getpid());
		// 2.1 創(chuàng)建共享內(nèi)存段
		int shmid = shmget(SHM_KEY, 8, IPC_CREAT|0666);
		if(shmid == -1)
		{
			perror("semget failed");
			exit(1);
		}
		
		// 2.2 映射共享內(nèi)存,得到虛擬地址
		void *p = shmat(shmid, 0, 0);
		 if((void *)-1 == p)
		{
			perror("shmat failed");
			exit(2);
		}
		
		// 2.3 讀寫共享內(nèi)存
		int *pi = p;
		*pi = 0xaaaaaaaa;
		*(pi+1) = 0x55555555;
		printf("子進(jìn)程[%d]寫入%x, %x\n", getpid(), *pi, *(pi+1));
		
		// 2.4 解除映射
		if(shmdt(p) == -1)
		{
			perror("shmdt failed");
			exit(3);
		}
		printf("子進(jìn)程[%d]解除映射, 結(jié)束進(jìn)程\n\n", getpid());
        return 0;
    }
	else if(pid > 0)// 父進(jìn)程
	{
		sleep(3); //延時(shí)一會(huì),讓子進(jìn)程先運(yùn)行
		printf("父進(jìn)程[%d]開始執(zhí)行, 獲取共享內(nèi)存段,準(zhǔn)備使用資源\n", getpid()); 
		// 3.1 獲取共享內(nèi)存段
		int shmid = shmget(SHM_KEY, 0, 0);
		if(shmid == -1)
		{
			perror("shmget failed");
			exit(1);
		}
		
		// 3.2 映射共享內(nèi)存,得到虛擬地址
		void *p = shmat(shmid, 0, 0);
		if((void *)-1 == p)
		{
			perror("shmat failed");
			exit(2);
		}
		
		// 3.3 讀寫共享內(nèi)存
		int x = *((int *)p);
		int y = *((int *)p + 1);
		printf("父進(jìn)程[%d]讀取數(shù)據(jù):x=%#x y=%#x\n",getpid(), x, y);
		
		// 3.4 解除映射
		if(shmdt(p) == -1)
		{
			perror("shmdt failed");
			exit(3);
		}
		printf("父進(jìn)程[%d]解除映射\n", getpid());
		
		// 3.5 銷毀共享內(nèi)存
		if(shmctl(shmid, IPC_RMID, NULL) == -1)
		{
			perror("shmctl");
			exit(4);
		}
		printf("父進(jìn)程[%d]銷毀共享內(nèi)存, 結(jié)束進(jìn)程\n", getpid());
        return 0;
	}
	else
	{
		printf("Error in fork\n"); 
        exit(1); 
	}
	
	return 0;
}

允許結(jié)果:
在這里插入圖片描述

在這里插入圖片描述

??六、總結(jié)

Linux 進(jìn)程間通信有10種方式,本文先介紹了5種:無(wú)名管道、命名管道、XSI消息隊(duì)列、XSI信號(hào)量、XSI共享內(nèi)存,下篇文章將會(huì)介紹剩下的5個(gè)方式:POSIX消息隊(duì)列、POSIX信號(hào)量、POSIX共享內(nèi)存、信號(hào)、網(wǎng)絡(luò)通信。

Linux 進(jìn)程間通信的10種方式(2)

在這里插入圖片描述
如果文章有幫助的話,點(diǎn)贊??、收藏?,支持一波,謝謝 ??????文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-824934.html

到了這里,關(guān)于【Linux C | 進(jìn)程】Linux 進(jìn)程間通信的10種方式(1)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

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

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

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

    2024年01月25日
    瀏覽(14)
  • 【Linux】進(jìn)程通信之管道通信詳解

    【Linux】進(jìn)程通信之管道通信詳解

    ?? 作者: 阿潤(rùn)菜菜 ?? 專欄: Linux系統(tǒng)編程 其實(shí)管道通信是Unix中最古老的進(jìn)程間通信的形式了: 管道通信是一種進(jìn)程間通信的方式,它可以讓一個(gè)進(jìn)程的輸出作為另一個(gè)進(jìn)程的輸入,實(shí)現(xiàn)數(shù)據(jù)的傳輸、資源的共享、事件的通知和進(jìn)程的控制。 管道通信分為兩種類型:匿名

    2023年04月19日
    瀏覽(46)
  • 【Linux】進(jìn)程通信之匿名管道通信

    【Linux】進(jìn)程通信之匿名管道通信

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

    2024年04月14日
    瀏覽(24)
  • Linux——進(jìn)程間通信、管道

    Linux——進(jìn)程間通信、管道

    進(jìn)程間的通信就是 在不同進(jìn)程之間傳播或交換信息。 舉個(gè)例子: 古時(shí),兩軍交戰(zhàn)不斬來(lái)使; 因?yàn)閮绍娀ハ嗍仟?dú)立的,所以使節(jié)就是兩軍之間傳話的進(jìn)行傳話的; 而在OS中,進(jìn)程之間也是相互獨(dú)立的,但某項(xiàng)工作并不是一個(gè)進(jìn)程就可以完成,而是多個(gè)進(jìn)程之間相互協(xié)助完成;

    2024年02月22日
    瀏覽(23)
  • Linux進(jìn)程通信:無(wú)名管道

    Linux進(jìn)程通信:無(wú)名管道

    (1)數(shù)據(jù)傳輸:進(jìn)程間數(shù)據(jù)傳輸; (2)通知事件:一個(gè)進(jìn)程向另一個(gè)或一組進(jìn)程發(fā)送消息,通知某個(gè)事件的發(fā)生(如子進(jìn)程終止時(shí)需通知父進(jìn)程); (3)資源共享:多個(gè)進(jìn)程共享資源,需要內(nèi)核提供同步互斥機(jī)制; (4)進(jìn)程控制:某進(jìn)程需要控制另一個(gè)進(jìn)程的執(zhí)行(如

    2023年04月24日
    瀏覽(23)
  • linux——進(jìn)程間通信——管道

    linux——進(jìn)程間通信——管道

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

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

    Linux——進(jìn)程間通信&&管道

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

    2024年04月09日
    瀏覽(27)
  • Linux——進(jìn)程間通信(管道)

    Linux——進(jìn)程間通信(管道)

    目錄 進(jìn)程通信的目的 管道 見見豬跑(舉個(gè)例子) 文件描述符fd與管道的關(guān)系(深度理解管道) 什么是管道? ?匿名管道 pipe函數(shù)概述 父子進(jìn)程通信時(shí)與文件描述符的關(guān)系圖(理解pipe函數(shù)的關(guān)鍵) pipe函數(shù)的使用 ?管道讀寫規(guī)則 管道的大小 自測(cè) ?使用man 7 pipe查看 使用ulimit -a查看 管

    2024年02月03日
    瀏覽(17)
  • 【Linux】進(jìn)程通信 — 管道

    【Linux】進(jìn)程通信 — 管道

    從本章開始,我們開始學(xué)習(xí)進(jìn)程通信相關(guān)的知識(shí),本章將來(lái)詳細(xì)探討一下管道,學(xué)習(xí)匿名管道和命名管道的原理和代碼實(shí)現(xiàn)等相關(guān)操作。目標(biāo)已經(jīng)確定,接下來(lái)就要搬好小板凳,準(zhǔn)備開講了…???????? 在我們之前的學(xué)習(xí)中,我們知道進(jìn)程是具獨(dú)立性的。但是不要以為進(jìn)程

    2024年02月16日
    瀏覽(17)
  • [Linux]進(jìn)程間通信--管道

    [Linux]進(jìn)程間通信--管道

    數(shù)據(jù)傳輸:一個(gè)進(jìn)程需要將它的數(shù)據(jù)發(fā)送給另一個(gè)進(jìn)程 。 資源共享:多個(gè)進(jìn)程之間共享同樣的資源。 通知事件:一個(gè)進(jìn)程需要向另一個(gè)或一組進(jìn)程發(fā)送消息,通知它(它們)發(fā)生了某種事件(如進(jìn)程終止時(shí)要通知父進(jìn)程)。 進(jìn)程控制:有些進(jìn)程希望完全控制另一個(gè)進(jìn)程的執(zhí)

    2024年02月09日
    瀏覽(15)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包