Comunicação entre processos com base na fila de mensagens e na memória compartilhada

Introduzir

Domine os princípios da comunicação entre processos com base em filas de mensagens e memória compartilhada

Projeto experimental

Comunicação entre processos com base na fila de mensagens e na memória compartilhada

Finalidade experimental

1. Aprofundar a compreensão do conceito de processo, esclarecer a diferença entre processo e programa e entender melhor a essência da execução simultânea.
2. Gerenciamento de processo mestre e comunicação de processo.
3. O mecanismo de comunicação de processo (IPC) do sistema Linux permite que grandes quantidades de dados sejam trocadas entre processos arbitrários.
4. O objetivo deste experimento é entender e estar familiarizado com:
5. Mecanismo de comunicação de mensagens suportado pelo Linux e seu método de uso
6. Princípio e método de uso da área de armazenamento compartilhado do sistema Linux.

Visualização experimental

1. Enfileiramento de Mensagens
1. Visão geral do Enfileiramento de Mensagens:
O Enfileiramento de Mensagens é uma lista vinculada de mensagens, armazenadas na memória e mantidas pelo kernel.
2. As características da
fila de mensagens : a fila de mensagens permite que um ou mais processos gravem ou leiam mensagens para ela, e cada mensagem tem um tipo; a
fila de mensagens pode implementar uma consulta aleatória das mensagens, e as mensagens não precisam ser as primeiras a entrar, as primeiras a sair. Leitura sequencial, você pode ler de acordo com o tipo de mensagem durante a programação; assim
como o pipe sem nome e o famoso pipe, ler a mensagem da fila de mensagens, os dados na fila de mensagens serão excluídos.
A mensagem na fila de mensagens também é formatada;
a mensagem só será excluída quando o kernel for reiniciado ou excluído manualmente.Se a fila de mensagens não for excluída manualmente, a fila de mensagens sempre existirá na memória; o
identificador da fila de mensagens identifica a mensagem Fila. A fila de mensagens é completa,
é única no sistema.
Segundo, memória compartilhada A memória
compartilhada permite que dois ou mais processos compartilhem uma determinada área de armazenamento.
A memória compartilhada é a maneira mais rápida de compartilhar dados entre processos.Um processo grava dados em uma área de memória compartilhada e todos os processos que compartilham essa área de memória podem ver imediatamente o conteúdo.
O uso da memória compartilhada deve prestar atenção à exclusão mútua de acesso a uma determinada área de armazenamento entre vários processos. Se um processo estiver gravando dados na área de memória compartilhada, nenhum outro processo deverá ler ou gravar os dados antes de concluir esta etapa.

Conteúdo experimental

1.
Crie uma fila de mensagens, envie e receba mensagens Crie uma fila de mensagens, chame msgget (), msgsnd (), msggrev (), msgctrl () e outras funções para enviar e receber mensagens entre os dois processos
Segundo, a criação, o anexo e a desconexão do armazenamento compartilhado
Crie memória compartilhada, use shmget (), shmat (), shmctl (), shmctl () e outras funções para obter comunicação entre os dois processos.

Equipamento experimental

Windows PC
Linux Ubuntu

Instruções básicas de design de princípios

Primeiro, o princípio de design:
para facilitar os resultados de operação e observação, um programa é usado como uma "introdução" e dois processos filhos, servidor e cliente, são criados através da função fork () para se comunicar.
Segundo, a fila de mensagens: O
servidor estabelece uma fila de mensagens com uma chave 75, aguardando mensagens enviadas por outros processos. Quando uma mensagem do tipo 1 é encontrada, ela serve como um sinal final, cancela a fila e sai do servidor. O servidor exibe uma frase "(Servidor) recebido o tipo de dados (n) é:" após receber uma mensagem; o
cliente usa uma fila de mensagens com uma chave 75 para enviar mensagens do tipo 10 para 1 sucessivamente e sai. A última mensagem é o sinal final exigido pelo servidor. Cada vez que o Cliente envia uma mensagem, ele exibe "(O cliente) enviou o tipo de dados (n) é:"; o
processo pai termina após a saída do servidor e do cliente.
3. Memória compartilhada: o
servidor estabelece uma fila de mensagens com uma chave 75, aguardando mensagens enviadas por outros processos. O servidor exibe uma mensagem "(Servidor) recebido" após receber uma mensagem; O
cliente usa uma fila de mensagens com uma chave 75 para receber mensagens na memória compartilhada. Cada vez que o Cliente envia uma mensagem, ele exibe um "(Cliente) enviado"; o
processo pai termina após a saída do servidor e do cliente.

Procedimento experimental

Primeiro, a fila de mensagens

1. Escreva um programa e use a bifurcação de chamadas do sistema () para criar dois servidores e clientes de processos filhos.O processo pai aguarda que os dois processos filhos terminem e depois sai.

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
int main(int argc ,char *argv[])
{

	pid_t pid;
	pid = fork();	
	if(pid <0)
	{
		printf("fork error\n");
	}
	if(pid ==0)
	{			
	}
	else
	{		
		pid_t pid;
		pid = fork();
		if(pid <0)
		{
			printf("fork error\n");
		}
		if(pid ==0)
		{	    
		}
		}else{
			wait(NULL);
			sleep(1);
			printf("Main process quit\n");	
		}	
	}	
	return 0;
}

2. Crie a estrutura de formato da mensagem da fila de mensagens.

typedef struct _msg
{
	long msgtype;
	char m[500];

}MSG;

3. No lado do cliente, crie uma fila de mensagens com um valor-chave de 75 e envie a string com o valor inicial de "abcdefghij" 10 vezes em um loop. Após cada envio, o ponteiro é deslocado um bit para obter um efeito diferente sempre que o conteúdo é enviado. Ao mesmo tempo, o tipo de mensagem de cada mensagem enviada é diminuído de 10 para 1. Quando a mensagem com o tipo 1 é enviada, o lado do cliente sai.

if(pid ==0)
	{
		int msgqid;
		int i = 0;
		msgqid = msgget(75,IPC_CREAT|0666);
		MSG msg;
		memset(msg.m,0,sizeof(msg.m));
		msg.msgtype = 10;
		char *a = "abcdefghij";
		for(;i < 11;i++)
		{
			strcpy(msg.m,a);
			sleep(1);
			msgsnd(msgqid,&msg,sizeof(msg.m),0);		
			printf("(Client)sent datetype %ld: %s\n",msg.msgtype,msg.m);
			msg.msgtype--;
			a++;
			if(msg.msgtype == 0 )
			{
				sleep(1);
				printf("Client sent over and shutdown now\n");
				exit(0);
			}
		}		
	}

4. No lado do servidor, crie uma fila de mensagens com um valor-chave de 75 e receba mensagens da fila de mensagens em tempo real.O tipo de mensagem recebida é diminuído de 10 para 1. Após receber a mensagem com o tipo de mensagem 1, a fila de mensagens é destruída. Sair.

if(pid ==0)
		{
	    int msgqid;
		int type = 10;
		msgqid = msgget(75,IPC_CREAT|0666);
		MSG msg;
		while(1)
		{
			msgrcv(msgqid,&msg,sizeof(msg.m),type,0);	
			printf("\t\t\t\t\t(Server)receiveddatetype %d: %s\n",type,msg.m);
			type--;
			if(type == 0)
			{
				msgctl(msgqid,IPC_RMID,NULL);
				sleep(1);
				printf("Sever get type 1 date and shutdown \n");
				sleep(1);
				printf("message queue destroyed\n");
				sleep(2);
				exit(0);
			}
		}

5. O efeito de execução é o seguinte:
Insira a descrição da imagem aqui

Segundo, memória compartilhada

  1. Escreva um programa, use a bifurcação de chamada do sistema () para criar dois processos filho e servidor e cliente; o processo pai aguarda que os dois processos filhos terminem e saiam.
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <fcntl.h>
#include <string.h>
#define BUF 2048
int main(int argc,char *argv[])
{
	pid_t pid;
	pid = fork();
	if(pid < 0)
	{
		perror("fork error\n");
	}
	if(pid == 0)
	{	
		
	}
	else{
	    pid_t pid;
		pid = fork();
		if(pid < 0)
		{
			perror("fork error\n");
         	}
		if(pid == 0)
		{
		
		}
		else{	
			wait(NULL);
			sleep(2);
			printf("Process quit\n");
		    }	
	    }
	return 0;
}
  1. No lado do cliente, crie uma memória compartilhada com um valor-chave de 75 e um tamanho de 2048 que possa ser lido e gravado. Após o mapeamento da memória compartilhada, a cadeia de caracteres com o valor inicial de "5201314" é enviada 10 vezes em um loop e o ponteiro é enviado sempre. Retroceda um pouco para obter um efeito diferente cada vez que o conteúdo for enviado. Até que a mensagem com o conteúdo de "4" seja enviada, o cliente terminará naturalmente.
if(pid == 0)
	{	
		int shmid;
		int i = 0;
		char *a = "5201314";
		shmid = shmget(75,BUF,SHM_R|SHM_W|IPC_CREAT);
		char *shmadd;
		shmadd = shmat(shmid,NULL,0);
		bzero(shmadd,BUF);
		for(;i < 7;i++){
			sleep(1);
			bzero(shmadd,BUF);
			strcpy(shmadd,a);
			printf("(Client) sent: %s\n",shmadd);
			a++;
		     }
	}

3. No lado do servidor e no cliente, crie uma memória compartilhada com um valor-chave de 75 e um tamanho de 2048 que possa ser lido e gravado.Depois que a memória compartilhada é mapeada, a mensagem enviada pelo cliente na memória compartilhada é recebida em tempo real e quando a recepção é concluída Após a mensagem com o conteúdo "4", retire o mapeamento da memória compartilhada, destrua a memória compartilhada e termine o processo.

if(pid == 0)
		{
		int shmid;
		shmid = shmget(75,BUF,SHM_R|SHM_W|IPC_CREAT);
		char *shmadd;
		shmadd = shmat(shmid,NULL,0);
		bzero(shmadd,BUF);
		while(1){
				sleep(1);
				printf("\t\t\t\t(Server) received: %s\n",shmadd);
				if(*shmadd == '4')
				{
					exit(0);
				}
			}
		shmdt(shmadd);
		shmctl(shmid,IPC_RMID,NULL);
		}

4. O efeito de execução é o seguinte:
Insira a descrição da imagem aqui

Experiência de análise

Análise: Desde que você domine os princípios de criação e controle de processos, criação de fila de mensagens e chamadas de funções relacionadas, criação de memória compartilhada e chamadas de funções relacionadas, você poderá concluí-las passo a passo de acordo com os respectivos princípios de comunicação .
Experiência: Através da operação prática deste experimento, percebi que o design de aplicativos Linux é realmente um curso altamente operacional.A operação prática é verificar e dominar o conhecimento teórico dos livros didáticos, fortalecer minha compreensão do Ubuntu e ser mais proficiente nele A melhor maneira de executar operações é experimentar os princípios de operação relacionados às filas de mensagens e memória compartilhada por meio de operações pessoais, e ganhar muito, o que estabelece uma base sólida para aprendizado futuro.

Resultados experimentais

Com o sucesso dos resultados do teste, a criação e o controle do processo, a criação da fila de mensagens e a comunicação entre processos e a criação da memória compartilhada na comunicação entre processos foram executadas com êxito. O objetivo do experimento foi alcançado e o experimento foi perfeitamente bem-sucedido!

Fim

É usado aqui para organizar notas, o conteúdo é apenas para referência

Publicado 3 artigos originais · Curtidas0 · Visitas 22

Acho que você gosta

Origin blog.csdn.net/qq_43711326/article/details/105453454
Recomendado
Clasificación