contente
Em segundo lugar, o que é memória compartilhada
Terceiro, a criação e uso de memória compartilhada
Quarto, use a memória compartilhada para alcançar a comunicação entre processos
1. Prepare um final de gravação
I. Introdução
A comunicação entre processos (IPC, InterProcess Communication) refere-se à disseminação ou troca de informações entre diferentes processos. Agora os métodos de comunicação entre processos usados pelo linux são: (1) pipes (pipe) e pipes nomeados (FIFO) (2) sinais ( sinal) (3) fila de mensagens (4) memória compartilhada (5) semáforo (6) soquete (soquete).
Sinais e pipes foram introduzidos antes. Hoje, vamos aprender como a memória compartilhada se comunica entre os processos.
Em segundo lugar, o que é memória compartilhada
- Diagrama de memória compartilhada
A memória compartilhada é um intervalo de endereços especial criado pelo IPC para um processo. Ele aparecerá no espaço de endereçamento do processo. Outros processos podem "conectar" o mesmo segmento de memória compartilhada ao seu próprio espaço de endereçamento. Como mostrado na FIG.
Observação:
: A memória compartilhada pode ser criada por um processo, mas a memória compartilhada não pertence a nenhum processo
: A memória compartilhada pertence ao sistema operacional e é gerenciada pelo sistema operacional
: Todos os processos podem acessar endereços de memória compartilhada como se fossem malloc alocados
: Se um processo gravar dados nessa memória compartilhada, as alterações serão vistas imediatamente por outros processos que tenham acesso à mesma memória compartilhada
- Digite o comando no terminal linux: o ipcs pode visualizar a fila de mensagens, o segmento de memória compartilhada e o grupo de números de sinal do sistema atual
O tamanho máximo de transferência do FIFO do pipe nomeado usado antes é de 65535 bytes, e o "arquivo" fifo usado é facilmente excluído pelo usuário, o que levará a erros de comunicação entre os processos . A memória compartilhada permite que dois processos não relacionados acessem A mesma parte do a memória lógica é muito eficiente , então vamos apresentar como a memória compartilhada é criada e usada no código.
Terceiro, a criação e uso de memória compartilhada
1. função shmget()
- Função: Criar memória compartilhada (não existir) ou obter memória compartilhada (existir).
#include <sys/ipc.h>
#include <sys/shm.h>Protótipo de função :
int shmget(chave_t chave, tamanho_tamanho, int shmflg);
Parâmetros :
key: (inteiro diferente de zero), que efetivamente nomeia o segmento de memória compartilhada
size: a quantidade de memória que precisa ser compartilhada
shmflg: consiste em nove sinalizadores de permissão, seu uso é o mesmo que o sinalizador de modo usado ao criar arquivos
Valor de retorno :
Se a memória compartilhada for criada com sucesso, é retornado um inteiro não negativo, ou seja, o código de identificação deste segmento de memória compartilhada;
Retorna -1 em caso de falha.
Exemplo:
- criar uma memória compartilhada
#include <iostream>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
using namespace std;
int main()
{
int shmid = 0;
//不存在则创建共享内存,存在则获取
shmid = shmget((key_t)1001, 10086, IPC_CREAT | 0777);
if (shmid < 0)
{
perror("shmget error");
}
else
{
cout << "创建共享内存成功" << endl;
}
return 0;
}
- Através do comando: ipcs, você pode ver nosso segmento de memória compartilhada recém-criado com uma permissão de 777 e um número de bytes de 10086.
- ipcrm -m shmid excluir memória compartilhada
-
Ipcrm -a exclui tudo, exceto o segmento de memória originalmente criado pela raiz do sistema
Exclua a memória compartilhada criada na etapa anterior através do comando ipcrm
2. função shmat()
- Função: Quando a memória compartilhada é criada pela primeira vez, ela não pode ser acessada por nenhum processo. A função da função shmat() é iniciar o acesso à memória compartilhada e conectar a memória compartilhada ao espaço de endereçamento da atual processo.
#include <sys/types.h>
#include <sys/shm.h>Protótipo de função :
void *shmat(int shmid, const void *shmaddr, int shmflg);
Parâmetros :
shmid: identificador de memória compartilhada retornado pela função shmget()
shmaddr: o endereço onde a memória compartilhada será colocada quando estiver conectada ao processo atual
shmflg: pode ser especificado como 0,
Valor de retorno :
Sucesso: retorna um ponteiro, o ponteiro aponta para o primeiro byte da memória compartilhada, que é o primeiro endereço da memória compartilhada
Falha: -1 é retornado.
3. função shmdt()
- Função: separa a memória compartilhada do processo atual
#include <sys/types.h>
#include <sys/shm.h>Protótipo de função :
int shmdt(const void *shmaddr);
Parâmetros :
shmaddr: o ponteiro de endereço retornado pela função shmat()
Valor de retorno :
sucesso: retorno 0,
Falha: retornar -1.
Observação:
: Usar a função shmdt() para sair da memória compartilhada não significa excluí-la, apenas que o processo atual não pode mais acessá-la.
Quarto, use a memória compartilhada para alcançar a comunicação entre processos
Veja a seguir um pequeno exemplo de uso de memória compartilhada para implementar uma comunicação simples entre dois processos não relacionados.
1. Prepare um final de gravação
- Gravar dados na memória compartilhada, os dados gravados são { "10001", "admin" };
#include <iostream>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <string.h>
using namespace std;
typedef struct student
{
char id[10];
char name[10];
}STU;
int main()
{
STU stu = { "10001","admin" };
void* shamdaddr = NULL;
int shmid = 0;
//不存在则创建共享内存,存在则获取
shmid = shmget((key_t)1001, 10086, IPC_CREAT | 0777);
if (shmid < 0)
{
perror("shmget error");
}
else
{
//连接共享内存,首地址存到 shamdaddr
shamdaddr = shmat(shmid, NULL, 0);
memcpy(shamdaddr, &stu, sizeof(STU));//内存拷贝 即:将stu结构体的数据写入共享内存中
cout << "写入数据成功" << endl;
//结束连接 当前进程脱离共享内存
shmdt(shamdaddr);
}
return 0;
}
2. Prepare um leitor
- Ler dados da memória compartilhada e armazená-los em uma estrutura vazia.
#include <iostream>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <string.h>
using namespace std;
typedef struct student
{
char id[10];
char name[10];
}STU;
int main()
{
STU stu = { 0 };
void* shamdaddr = NULL;
int shmid = 0;
//不存在则创建共享内存,存在则获取
shmid = shmget((key_t)1001, 10086, IPC_CREAT | 0777);
if (shmid < 0)
{
perror("shmget error");
}
else
{
//连接共享内存,首地址存到 shamdaddr
shamdaddr = shmat(shmid, NULL, 0);
memcpy(&stu, shamdaddr, sizeof(stu)); //内存拷贝 即:将共享内存中的数据写入空的结构体中
cout << "获取数据成功" << endl;
cout << stu.id << endl;
cout << stu.name << endl;
//结束连接 当前进程脱离共享内存
shmdt(shamdaddr);
}
return 0;
}
O código dos dois projetos é semelhante, a diferença é que um grava os dados e o outro lê os dados.
3. Resultados do teste
- Compilado por g++ no linux e executado no modo ./, os resultados do teste são os seguintes
leitura e escrita normais
O segmento de memória compartilhada também é criado normalmente, e o número de conexões é 0, pois o programa terminou.
Os dados na memória compartilhada sempre existirão sem modificação e o conteúdo pode ser lido repetidamente.
A originalidade não é fácil, por favor indique a fonte ao reimprimir.
Se for útil para você, você pode clicar três vezes e será atualizado continuamente (hee hee).