Полное руководство по межпроцессному общению IPC: принципы и практика использования различных механизмов
Полное руководство по межпроцессному общению IPC: принципы и практика использования различных механизмов

1. Введение

В современных вычислительных системах многопроцессные среды стали стандартом. По мере роста вычислительных потребностей и увеличения сложности приложений один процесс часто не может выполнить все задачи независимо. Чтобы повысить гибкость, производительность и надежность системы, сотрудничество между несколькими процессами стало неизбежным выбором. Это приводит к ключевому вопросу: как эффективно и безопасно реализовать обмен данными и связь между процессами? Это основная проблема межпроцессного взаимодействия (IPC).

Важность межпроцессного взаимодействия:

Межпроцессное взаимодействие относится к механизму передачи информации между различными процессами. В многопроцессной системе отдельным процессам может потребоваться совместное использование данных, координация работы или обмен информацией о состоянии. Например, на веб-сервере рабочему процессу может потребоваться взаимодействовать с процессом управления для получения конфигурации или статуса отчета. В системе обработки данных процессу-производителю и процессу-потребителю необходимо обменяться данными для выполнения задачи. Эти требования к коммуникации побудили разработать и внедрить механизм IPC.

Эффективный механизм IPC может не только повысить производительность системы и скорость отклика, но также обеспечить согласованность данных и стабильность системы. В некоторых случаях механизм IPC может даже стать ключевым компонентом системной архитектуры. Например, в распределенной системе или микросервисной архитектуре эффективность межпроцессного взаимодействия напрямую влияет на производительность всей системы.

Это руководство призвано глубоко изучить различные механизмы межпроцессного взаимодействия, от базовых знаний до практического применения, чтобы помочь читателям полностью понять принцип работы IPC и научиться выбирать и применять наиболее подходящий метод IPC в различных сценариях. В этой статье будут рассмотрены следующие аспекты:

  1. Основные понятия межпроцессного взаимодействия:представлятьIPCопределение、Сценарии применения и основные проблемы,Заложите основу для последующего углубленного понимания.
  2. Классический механизм IPC:Подробно опишите трубопровод、очередь сообщений、общая память、Сигнал、розетка Принцип традиционного механизма IPC, такого как файлы с отображением в памяти., недостатки и практическое применение.

2. Основные понятия межпроцессного взаимодействия

Межпроцессное взаимодействие — это механизм, обычно предоставляемый операционной системой (или операционной системой). Основная цель или задача этого механизма — обеспечить связь между несколькими процессами. Короче говоря, взаимодействие позволяет одному процессу сообщить другому процессу о том, что произошли определенные события.

2.1. Определение межпроцессного взаимодействия (IPC).

определение:межпроцессное взаимодействие используется для обмена полезной информацией между многочисленными потоками в одном или нескольких процессах (или программе).。Поскольку процессы имеют независимые адресные пространстваиресурс,Прямой доступ к данным друг друга невозможен. поэтому,IPCмеханизм обеспечивает метод обмена данными через интерфейс, предоставляемый операционной системой. IPCмеханизм – это не только передача данных,Сюда также входит синхронизация и координация между процессами.

2.2. Сценарии применения МПК.

  • Обмен данными:Многим процессам нужен доступили Изменить тот же набор данных。Например,Многим процессам в системе базы данных может потребоваться доступ к общим кэшированным таблицам базы данных.
  • координация задач:Процессы должны работать вместе для выполнения сложных задач.。Например,существовать веб-сервер,Рабочий процесс должен координироваться с основным процессом для обработки запросов.
  • обновление статуса:Процессы должны передавать друг другу информацию о состоянии, чтобы облегчить общую координацию системы.。Например,Основной процесс в системе мониторинга требует получения каждогодочерний процессрабочее состояние。

2.3. Основные проблемы МПК.

  • Синхронизация и взаимное исключение:Несколько процессов могут получить доступ к общему ресурсу одновременноресурс,Необходимо обеспечить согласованность данныхиизбегать конфликта。синхронныймеханизм(как замоки Сигналколичество)Помогите контролировать общий доступресурсиздоступ。
  • согласованность данных:убеждатьсясуществовать Данные, передаваемые между процессамисуществовать Приемник может точно восстановить。согласованность Проблемы с данными обычно требуют разработки разумного формата данных и механизма проверки.
  • производительность:IPCмеханизмэффективность системыпроизводительностьиметь прямое влияние。Выберите правильныйIPCмеханизм Можетсуществовать При удовлетворении потребностей в общении,Максимально сократите расходы на коммуникацию.
  • безопасность:убеждатьсяIPCданные в процессебезопасностьиконфиденциальность,Предотвратите несанкционированный доступ и подделку данных.

2.4. Классификация и выбор механизмов МПК.

  • общение на основе сообщений:нравитьсяочередь сообщений、розеткаждать,Обмен данными между процессами осуществляется посредством передачи сообщений.
  • Связь на основе общей памяти:нравитьсяобщая память, отображенный в памяти файл,проходитьобщая Область памяти реализует межпроцессное взаимодействие. данными。
  • сигнальная связь:нравиться Сигналмеханизм,проходитьотправлятьиперенимать Сигнал Реализация уведомления о событиях между процессамиисинхронный。

Выбор механизма IPC:

  • Объем данных и частота связи:для большогоколичестводанныеи Частое общение,Нужен эффективный механизм,нравитьсяобщая память。
  • согласованность данных Требовать:Высокая консистенция Требовать Должен быть надежнымизмеханизм,нравитьсяочередь сообщений。
  • в реальном времени:Системы реального времени строго следят за задержками связи.Требовать,Необходимо отдать приоритет низкой задержке IPCмеханизм,нравиться Сигнал。
  • Сложность и обслуживание:некоторыйIPCмеханизмвыполнитьи Обслуживание более сложное,Необходимо учитывать затраты на разработку и обслуживание системы.

3. Классический механизм IPC.

  • Трубка.
  • Очереди сообщений.
  • Общая память.
  • Сигналы.
  • Розетки.
  • Файл с отображением в памяти (Memory-Mapped Files)

3.1. Труба

Конвейер — это односторонний канал данных, то есть данные в канале данных могут перемещаться одновременно только в одном направлении.。Это полудуплексный метод,Для достижения полного дуплекса,Нужна другая труба,сформировать набор двойных каналов,Чтобы иметь возможность отправлять и получать данные между двумя процессами. в целом,Он использует стандартные методы ввода и вывода. Эти каналы используются во всех типах POSIX Windows.

существоватьUnixи категорияUnix система,Трубы обычно используются для материнских дочерний. процессмеждуили ВОЗпроходитьforkсоздаватьизпроцессмеждуобщаться,потому чтосуществуют Нет смысла использовать каналы внутри процесса。Есть два типа труб:анонимная трубкаи Именованный канал (FIFO)。

Трубы, вероятно, являются одним из наиболее широко используемых методов IPC на местном уровне. Каналы фактически реализуются с использованием раздела памяти ядра. Системный вызов всегда создает канал и две связанные спецификации файла для чтения и записи в канал.

преимущество:

  • Реализация проста и подходит для простого взаимодействия родительских и дочерних процессов.
  • Каналы используют конвейерные буферы для управления потоком данных между процессами чтения и записи.

недостаток:

  • Односторонняя передача ограничивает сценарии применения и не подходит для двусторонней связи.
  • Поскольку он основан на памяти, эффективность передачи больших объемов данных может быть низкой.
  • анонимная трубка обычно может использоваться только между связанными процессами, но не может взаимодействовать между двумя процессами.

Как работает трубопровод:

  1. Создание трубы:существоватьUnixв системе,Можетиспользоватьpipe()Системный вызовсоздаватьтруба。Этот вызов вернет два файловых дескриптора,один для операций чтения,один для операций записи。Например: int pipefd[2]; if (pipe(pipefd) == -1) { perror("pipe"); exit(EXIT_FAILURE); } pipefd[0]для чтения данных,иpipefd[1]для записи данных。Два файловых дескриптора образуют односторонний канал потока данных.。
  2. Передача данных:
    • Операции записи: процесс может записывать данные в канал, записывая дескриптор файла. Данные будут храниться в буфере канала до тех пор, пока они не будут прочитаны. константа char *message = "Hello, World!"; write(pipefd[1], message, strlen(message));
    • Операция чтения: другой процесс может читать данные из канала, читая дескриптор файла. Операция чтения извлекает данные из буфера и возвращает их вызывающему процессу. char buffer[128]; ssize_t bytesRead = read(pipefd[0], buffer, sizeof(buffer));
  3. Использование трубы:
    • существоватьмежпроцессное Во взаимодействии обычно есть два использования. процесса Трубы для обмена данными。Например,родительский процесссоздаватьтрубопровод,исуществоватьfork()после Волятрубопроводиз Дескрипторы файлов для чтения и записи передаютсядочерний процессиродительский процесс。
    • дочерний процесс Может Воляданныеписатьтрубопровод,родительский процесс Затем изтрубопроводсередина读取данные。в это время,Потоки данных существуют между двумя процессами,Передача данных между процессами осуществляется через каналы.

Различают анонимные каналы и именованные каналы:

  • анонимная трубка:анонимная трубка Самый простой тип канала. Это временный односторонний канал данных, обычно используемый для связи между процессами со связанными отношениями (например, родительско-дочерними процессами). анонимный трубкабез имени,онисуществоватьтрубопроводсоздаватьтолько когдасуществовать Действителен в рамках процесса,К нему не могут получить доступ другие процессы в системе.
  • Именованный канал (FIFO):имятрубопроводдаимяизспециальный файл,этосуществоватьдокументв системежитьсуществовать,Обеспечивает связь между несвязанными процессами. Таким образом, между несвязанными процессами может быть достигнута двусторонняя и односторонняя связь.,и不需要процесс间有直接из Родство。использоватьmkfifo()функция Создать именованный канал,И выполнить операции чтения и записи по пути к файлу: mkfifo("/tmp/myfifo", 0666);

Пример кода:

Язык кода:javascript
копировать
// анонимная трубка
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

int main() {
    int pipefd[2];
    pid_t pid;
    char buffer[128];
    
    if (pipe(pipefd) == -1) {
        perror("pipe");
        exit(EXIT_FAILURE);
    }
    
    if ((pid = fork()) == -1) {
        perror("fork");
        exit(EXIT_FAILURE);
    }
    
    if (pid == 0) { // дочерний процесс
        close(pipefd[0]); // Закрыть чтение
        const char *message = "Hello from child";
        write(pipefd[1], message, strlen(message) + 1);
        close(pipefd[1]);
        exit(EXIT_SUCCESS);
    } else { // родительский процесс
        close(pipefd[1]); // Закрыть сторону записи
        read(pipefd[0], buffer, sizeof(buffer));
        printf("Received message: %s\n", buffer);
        close(pipefd[0]);
    }
    
    return 0;
}
Язык кода:javascript
копировать
// Именованный канал (FIFO)
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

int main() {
    const char *fifo = "/tmp/myfifo";
    char buffer[128];
    
    // Создать именованный канал
    if (mkfifo(fifo, 0666) == -1) {
        perror("mkfifo");
        exit(EXIT_FAILURE);
    }
    
    pid_t pid;
    if ((pid = fork()) == -1) {
        perror("fork");
        exit(EXIT_FAILURE);
    }
    
    if (pid == 0) { // дочерний процесс
        int fd = open(fifo, O_WRONLY);
        const char *message = "Hello from FIFO";
        write(fd, message, strlen(message) + 1);
        close(fd);
        exit(EXIT_SUCCESS);
    } else { // родительский процесс
        int fd = open(fifo, O_RDONLY);
        read(fd, buffer, sizeof(buffer));
        printf("Received message: %s\n", buffer);
        close(fd);
    }
    
    // Удалить именованный канал
    unlink(fifo);
    
    return 0;
}

Сценарии применения:

Каналы часто используются для реализации простой передачи данных между родительскими и дочерними процессами или для чтения стандартного вывода процесса на другом конце канала. В сценариях оболочки каналы широко используются для передачи вывода одной команды другой команде в качестве входных данных. Например:

Язык кода:javascript
копировать
ls | grep "txt"

эта команда ВоляlsВывод команды передается вgrepкоманда для фильтрации,Используйте каналы для передачи данных между двумя командами.

3.2. Очереди сообщений

Очередь сообщений позволяет процессам обмениваться данными в виде сообщений между двумя процессами. Он позволяет процессам взаимодействовать асинхронно, отправляя друг другу сообщения, при этом сообщения хранятся в очереди, ожидая обработки и удаляются после обработки.

Очередь сообщений — это буфер, используемый в среде с неразделяемой памятью, где задачи взаимодействуют путем передачи сообщений друг другу, а не путем доступа к общим переменным. Задачи используют общий пул буферов. Очередь сообщений представляет собой неограниченную очередь FIFO, которая предотвращает одновременный доступ из разных потоков.

Определение: Очередь сообщений обеспечивает асинхронный протокол связи. Отправителю и получателю сообщения не требуется одновременно взаимодействовать с очередью сообщений.

Проще говоря, очередь сообщений работает как почтовый ящик: несколько процессов могут отправлять сообщения в очередь сообщений, а получатели могут извлекать сообщения из очереди.

События асинхронны. Когда класс отправляет событие другому классу, он не отправляет его непосредственно целевому реактивному классу, а вместо этого передает событие в очередь сообщений операционной системы. Когда целевой класс готов обработать событие, он извлекает событие из заголовка очереди сообщений. Вместо этого вы можете использовать триггерные действия для доставки событий синхронизации.

Многие задачи могут записывать сообщения в очередь, но только одна задача может одновременно читать сообщения из очереди. Читатель ожидает в очереди сообщений, пока не появится сообщение для обработки. Сообщения могут быть любого размера.

Очередь сообщений — это программный компонент, который обеспечивает связь между приложениями в микросервисах и бессерверных инфраструктурах. Сообщения передаются и принимаются с использованием асинхронного протокола связи, который ставит сообщения в очередь и не требует немедленного ответа от получателя.

преимущество:

  • Асинхронная связь: Отправить процесс Не нужно ждатьпроцесс получения Обработать сообщение немедленно,Может эффективно переходить к другим задачам,Улучшена пропускная способность системы и скорость отклика.
  • Развязка: 不同процессмежду Можетвзаимное общение,Не зная внутренней структуры или механизма управления другой стороны.,Уменьшает сложность системы и сложность обслуживания.
  • Гибкая обработка сообщений: В зависимости от содержания сообщения могут быть приняты различные стратегии обработки, могут быть реализованы различные функции и гибко обработаны различные типы данных.
  • безопасность: Вы можете использовать механизм контроля разрешений, чтобы защитить права доступа к очереди сообщений и обеспечить безопасность данных.
  • Механизм очереди: Поскольку сообщение сохраняетсясуществоватьв очереди,Порядок сообщений сохраняется.,Гарантирует, что сообщения принимаются и обрабатываются в указанном порядке.

недостаток:

  • Накладные расходы на ресурсы: Создание и управление очередью сообщениям необходимо потреблять системные ресурсы, включая память и время системных вызовов.
  • Сложность: По сравнению с другими простыми механизмами IPC, в свою очередь Использование сообщений требует понимания таких понятий, как структура сообщения, настройки разрешений и механизм синхронизации.
  • производительность: существовать В параллельном сценарии, если в свою очередь сообщения слишком длинные,Может возникнуть отставание, поскольку скорость обработки сообщений не соответствует скорости отправки.,Влиять на системупроизводительность。
  • Ограничено определенными типами сообщений обработки: очередь сообщений больше подходит для обработки полных сообщений с автономной информацией.,хотя существуют и имеют дело с ограниченными типами данных,Например, для синхронизации сигналов более рекомендуется использовать другие механизмы.,Например Сигналколичество。

В программе используются четыре важные функции для реализации IPC с использованием очередей сообщений:

  • msgget(key_t key, int msgflg): Используется для создания или открытия поворота сообщения. Первый параметр — это система именования, в свою очередь сообщенийключ,использоватьftokсоздавать;Второй параметр используется дляочередь Тексты назначают разрешения.
  • msgsnd(int msqid, const void *msg_ptr, size_t msg_sz, int msgflg): Используется для отправки сообщений в очередь сообщения. Последний параметр управляет существованиеочередью. сообщений заполнено или Что происходит, когда достигается системный лимит сообщений в очереди.
  • msgrcv(int msqid, void *msg_ptr, size_t msg_sz, long int msgtype, int msgflg): Используется для получения сообщений из очереди сообщений.
  • msgctl(int msqid, int command, struct msqid_ds *buf): для контроля сообщений, таких как изменение разрешений, получение сообщенийинформацияждатьждать。второй параметр МожетиметьIPC_STATIPC_SETIPC_RMIDодин из。

Шаги по выполнению IPC с использованием очереди сообщений:

  1. Создайте новую очередь или msgget() Откройте существующую очередь.
  2. Новые новости от msgsnd() Добавьте в конец очереди. Каждое сообщение имеет положительное длинное поле, неотрицательную длину и фактические байты данных (соответствующие длине), все из которых указываются при добавлении сообщения в очередь. msgsnd()
  3. Новости по msgrcv() Возьмите его из очереди. Нам не обязательно получать сообщения в порядке поступления. Вместо этого вы можете получить сообщение на основе его поля типа.
  4. очередь сообщений msgctl()Выполнение контрольных операций。

Пример записи в очередь сообщений:

Язык кода:javascript
копировать
#include<stdlib.h>  
#include<stdio.h>  
#include<string.h>  
#include<unistd.h>  
#include<sys/types.h>  
#include<sys/ipc.h>  
#include<sys/msg.h>  
#define MAX_TEXT 512   //maximum length of the message that can be sent allowed  
struct my_msg{  
    long int msg_type;  
    char some_text[MAX_TEXT];  
};  
int main()  
{  
    int running=1;  
    int msgid;  
    struct my_msg some_data;  
    char buffer[50]; //array to store user input  
    msgid=msgget((key_t)14534,0666|IPC_CREAT);  
    if (msgid == -1) {  
		printf("Error in creating queue\n");  
		exit(0);  
    }  
	while(running) {  
		printf("Enter some text:\n");  
		fgets(buffer,50,stdin);  
		some_data.msg_type=1;  
		strcpy(some_data.some_text,buffer);  
		if(msgsnd(msgid,(void *)&some_data, MAX_TEXT,0)==-1) {  
		 	printf("Msg not sent\n");  
		}  
		if(strncmp(buffer,"end",3)==0)  {  
			running=0;  
		}  
	}  
}  

Прочитайте очередь сообщений:

Язык кода:javascript
копировать
#include<stdlib.h>  
#include<stdio.h>  
#include<string.h>  
#include<unistd.h>  
#include<sys/types.h>  
#include<sys/ipc.h>  
#include<sys/msg.h>  
struct my_msg{  
	long int msg_type;  
	char some_text[BUFSIZ];  
};  
int main()  
{  
	int running=1;  
	int msgid;  
	struct my_msg some_data;  
	long int msg_to_rec=0;  
	msgid=msgget((key_t)12345,0666|IPC_CREAT);  
	while(running)  {  
	    msgrcv(msgid,(void *)&some_data,BUFSIZ,msg_to_rec,0);                   
	    printf("Data received: %s\n",some_data.some_text);  
	    if(strncmp(some_data.some_text,"end",3)==0)  
	    	running=0;  
	}  
	 msgctl(msgid,IPC_RMID,0);  
 }  

3.3. Общая память.

Общая память — это память, совместно используемая двумя или более процессами, позволяющая нескольким процессам получать доступ к одному и тому же блоку памяти и совместно использовать его. Каждый процесс имеет свое собственное адресное пространство; если какой-либо процесс хочет передать некоторую информацию из своего собственного адресного пространства другим процессам, он может использовать только технологию общей памяти IPC (межпроцессное взаимодействие).

Общая память — самый быстрый механизм межпроцессного взаимодействия.。Операционная система Воля Сегмент памяти в адресном пространстве нескольких процессов сопоставляется с сегментом памяти и считывается.иписать,без вызова функций операционной системы.

Для приложений, которые обмениваются большими объемами данных, общая память намного превосходит технологию очереди сообщений, поскольку очередь сообщений IPC требует системного вызова для каждого обмена данными.

Обычно взаимосвязанное взаимодействие процессов осуществляется с помощью каналов или именованных каналов. Несвязанное взаимодействие процессов может использовать именованные каналы или общую память, очереди сообщений и т. д. Однако проблема с каналами, FIFO и очередями сообщений заключается в том, что обмен информацией между двумя процессами происходит через ядро, требуя в общей сложности 4 копии данных (2 чтения и 2 записи). Таким образом, общая память позволяет двум или более процессам совместно использовать сегмент памяти. При использовании общей памяти данные копируются только дважды: из входного файла в общую память и из общей памяти в выходной файл.

При создании общих областей памяти в двух или более процессах нет гарантии, что эти области будут размещены по одному и тому же базовому адресу. Когда требуется синхронизация, можно использовать семафоры.

Есть две функции shmget() и shmat() для использования общей памяти IPC。shmget() функция используется для создания сегмента общей памяти, а shmat()функцияиспользуется для Воля Присоединение общего сегмента и адресного пространства процесса。

Язык кода:javascript
копировать
#include <sys/ipc.h>   
#include <sys/shm.h>   

int shmget (key_t key, size_t size, int shmflg);  

void *shmat(int shmid, const void *shmaddr, int shmflg);  

Как IPC работает с использованием общей памяти? Использование процесса shmget() Создайте сегмент общей памяти. Первоначальный владелец сегмента общей памяти может использовать shmctl()Воля Право собственности передано другому пользователю。этовозвращаться Может Отменить это назначение。Другие с соответствующими разрешениямипроцесс может использовать shmctl()существоватьобщая памятьвыполнять различные функции управления на сегменте。

После создания вы можете использовать shmat()Воля Общий сегмент прикреплен к адресному пространству процесса.。Можетиспользовать shmdt() Отделите это. Дополнительный процесс должен иметь shmat()соответствующие разрешения。После добавления,Процессы могут читать и записывать сегменты,Потому что разрешения, запрошенные в операции добавления, позволяют это. Общий сегмент может быть присоединен несколько раз одним и тем же процессом.

Сегменты общей памяти состоят из уникальных ID описание структуры управления, ID Указывает на область физической памяти. Идентификатор сегмента называется shmid。общая памятьструктура управления сегментомипрототипизструктураопределение Можетсуществовать <sys/shm.h> нашел в.

Пример использования:

Язык кода:javascript
копировать
#include<stdio.h>  
#include<stdlib.h>  
#include<unistd.h>  
#include<sys/shm.h>  
#include<string.h>  
int main()  
{  
	int i;  
	void *shared_memory;  
	char buff[100];  
	int shmid;  
	shmid=shmget((key_t)2345, 1024, 0666|IPC_CREAT);   
	//creates shared memory segment with key 2345, having size 1024 bytes. 
	printf("Key of shared memory is %d\n",shmid);  
	shared_memory=shmat(shmid,NULL,0);   
	//process attached to shared memory segment  
	printf("Process attached at %p\n",shared_memory);   
	//this prints the address where the segment is attached with this process  
	printf("Enter some data to write to shared memory\n");  
	read(0,buff,100); //get some input from user  
	strcpy(shared_memory,buff); //data written to shared memory  
	printf("You wrote : %s\n",(char *)shared_memory);  
}  
Язык кода:javascript
копировать
#include<stdio.h>  
#include<stdlib.h>  
#include<unistd.h>  
#include<sys/shm.h>  
#include<string.h>  
int main()  
{  
	int i;  
	void *shared_memory;  
	char buff[100];  
	int shmid;  
	shmid=shmget((key_t)2345, 1024, 0666);  
	printf("Key of shared memory is %d\n",shmid);  
	shared_memory=shmat(shmid,NULL,0); //process attached to shared memory segment  
	printf("Process attached at %p\n",shared_memory);  
	printf("Data read from shared memory is : %s\n",(char *)shared_memory);  
}  

3.4. Сигналы

существовать Операционная системаимежпроцессное взаимодействиесередина,Сигналы — важный механизм,Используется для уведомления процесса о том, что произошло какое-то событие или исключение.

Сигналы — это асинхронный механизм уведомлений, используемый для отправки уведомлений процессам на уровне программного обеспечения. Обычно его используют в следующих ситуациях:

  • Межпроцессное взаимодействие (IPC): Сигналы могут использоваться для уведомления процесса о том, что произошло определенное событие, например, когда пользователь набирает клавишу прерывания (например, Ctrl+C) или завершает дочерний процесс и т. д.
  • Необычные события: Например, ошибки доступа к памяти (такие как ошибки сегментации), переполнение чисел с плавающей запятой и другие аппаратные исключения будут преобразованы операционной системой в сигналы и отправлены соответствующему процессу.
  • Управление системой: Операционная система может заставить процесс выполнить определенные действия с помощью сигналов, таких как прерывание процесса, перезапуск процесса и т. д.

Каждый сигнал представлен уникальным целым числом, которое обычно определяется как макрос в <signal.h> в заголовочном файле. Некоторые общие сигналы включают в себя:

  • SIGINT (2): Сигнал прерывания терминала обычно инициируется нажатием пользователем Ctrl+C.
  • SIGKILL (9): Сигнал завершения, который нельзя игнорировать и который используется для принудительного завершения процесса.
  • SIGTERM (15): Сигнал завершения, используемый для нормального завершения процесса.
  • SIGSEGV (11): Ошибка сегментации, вызванная недопустимой ссылкой на память.
  • SIGCHLD (17): Сигнал уведомления об изменении состояния дочернего процесса, обычно отправляемый родительскому процессу, когда дочерний процесс завершается или завершается.

Отправка и обработка сигналов:

  • отправлять Сигнал: Можно использовать системные вызовы kill(pid, sig) к указанному процессу pid отправить сигнал sig
  • захватывать Сигнал: Процесс может захватывать и обрабатывать сигналы, зарегистрировав функцию обработки сигналов. использовать signal(sig, handler) или sigaction(sig, &act, &oldact) function для указания функции обработки сигнала.
  • Функция обработки сигнала: Функция обработки сигналов — это специальная функция, которая управляет поведением при возникновении определенного сигнала. Эти функции должны соответствовать определенному формату, обычно использующему void handler(int sig) Такое заявление.

Рекомендации по обработке сигналов:

  • Асинхронный характер: Сигнал Прибытие асинхронное,То есть процесс не может предсказать, когда поступит сигнал. поэтому,Сигналиметь дело сфункциядолжен быть максимально простымибыстрый。
  • Реентерабельность: потому что Сигнал Можетсуществоватьв любое времясередина断процесс执行,Поэтому функция обработки сигналов должна быть реентерабельной.,То есть его можно безопасно вызвать еще раз во время собственного выполнения.
  • Экранирование сигнала: процесс может использовать sigprocmask() функциязаблокировать(Предотвращать)или Разблокировать определенные Сигнал,контролироватьсуществоватькогдаперениматьнекоторый Сигнал。

Пример, используйте signal() функция захвата и обработки SIGINT Сигнал:

Язык кода:javascript
копировать
#include <stdio.h>
#include <signal.h>
#include <unistd.h>

void sigint_handler(int sig) {
    printf("Caught SIGINT, exiting...");
    exit(0);  // или Автор выполняет некоторую работу по очистке и затем выходит
}

int main() {
    signal(SIGINT, sigint_handler);

    printf("Waiting for SIGINT (Ctrl+C)...");

    while (1) {
        sleep(1);  // Продолжайте работу программы
    }

    return 0;
}

Сигнал Хотя в основном используется для событий уведомленийи Обработка исключений,Но его также можно использовать для простого межпроцессного взаимодействия.

Отправить процесс (sender.c)

Язык кода:javascript
копировать
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>

#define SIG_CUSTOM SIGUSR1  // Пользовательский сигнал

void error_handling(char *msg) {
    perror(msg);
    exit(EXIT_FAILURE);
}

int main() {
    pid_t pid = fork();  // создаватьдочерний процесс
    if (pid < 0) {
        error_handling("Fork error");
    } else if (pid == 0) {
        // дочерний процесс(процесс получения)
        execl("./receiver", "receiver", NULL);  // Выполнить процесс полученияпрограмма        error_handling("Exec error");
    } else {
        // родительский процесс(Отправить процесс)
        sleep(1);  // ждатьобращатьсядочерний инициализация процесса завершена

        printf("Sending signal to child process (PID: %d)...\
", pid);
        if (kill(pid, SIG_CUSTOM) == -1) {
            error_handling("Kill error");
        }

        printf("Signal sent.\
");
    }

    return 0;
}

процесс получения (receiver.c)

Язык кода:javascript
копировать
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>

#define SIG_CUSTOM SIGUSR1  // Пользовательский сигнал

void sig_handler(int sig) {
    if (sig == SIG_CUSTOM) {
        printf("Received custom signal SIGUSR1.\
");
    }
}

int main() {
    struct sigaction act;
    act.sa_handler = sig_handler;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;

    // настраивать Пользовательский сигнализиметь дело сфункция
    if (sigaction(SIG_CUSTOM, &act, NULL) == -1) {
        perror("Sigaction error");
        exit(EXIT_FAILURE);
    }

    printf("Waiting for signal...\
");

    while (1) {
        sleep(1);  // Продолжайте работу программы
    }

    return 0;
}

Скомпилируйте и запустите:

Язык кода:javascript
копировать
gcc sender.c -o sender
gcc receiver.c -o receiver

Затем запустите скомпилированный исполняемый файл в двух окнах терминала:

Язык кода:javascript
копировать
./receiver
Язык кода:javascript
копировать
./sender

3.5. Розетки

розетка(Socket)используется длясуществовать Разные хостыилитот же хозяиниз不同процессмеждуобщаться。этодаОдин из наиболее часто используемых методов сетевого программирования.,Позволяет процессам отправлять и получать данные по сети.

Основные понятия о сокетах:

  • Адрес сокета: Сокет состоит из двух адресов, а именно IP Адрес и номер порта. ИП Адрес идентифицирует хост в сети, а номер порта идентифицирует процесс на хосте.
  • Режим связи: розетка Может Поддержка различныхизрежим связи,включатьориентированный на соединениеизиНет связииз Два основных режима。
  • Метод передачи данных: Сокеты могут передавать данные двумя способами: потоками байтов или дейтаграммами, в зависимости от используемого протокола (например, TCP или UDP)。

Локальный сокет Розетка, также известная как Unix сокет домена) и Сетевая розетка Socket)да Два разныхизрозеткатип,В основном они различаются сценариями использования, методами реализации и характеристиками.

Локальный сокет Socket):

  • Сценарии использования: В основном он используется для связи между локальными процессами, то есть связи между разными процессами, работающими на одной машине. Они не проходят через стек сетевых протоколов, скорость связи выше, и они подходят для приложений, требующих высокой эффективности и безопасности Сценарии. применения。
  • Метод реализации: существование хранится в виде файла в файловой системе, обычно расположенной в /tmp Оглавлениеили ВОЗ系统指定из临时Оглавление下。местныйрозеткаиспользоватьдокумент系统из Разрешениямеханизмконтролировать доступ。
  • адрес: Адрес локального сокета — это путь к файловой системе, обычно хранящийся в существующей форме файловой системы, например /tmp/mysocket
  • преимущество: Высокая скорость передачи и высокая эффективность связи поддерживает несколько семейств протоколов (например, UNIX розетка и Netlink розетки и др.).
  • недостаток: Ограничено только локальным общением, не может общаться напрямую через границы сети.

Сетевой разъем:

  • Сценарии использования: используется длясетевая комнатаизпроцесс通信,Может обмениваться данными между разными хостами,Это основа для реализации сетевых приложений.
  • Метод реализации: Используйте стек сетевых протоколов для передачи данных и обмена данными через сетевой интерфейс. Общие сетевые розетки TCP розетка и UDP Розетки и т. д.
  • адрес: Адрес сетевого сокета задается выражением IP Он состоит из адреса и номера порта и используется для идентификации хоста и процесса в сети.
  • преимущество: Он может реализовать межсетевую связь и поддерживать потребности связи в различных сетевых средах, таких как глобальная сеть (WAN) и локальная сеть (LAN).
  • недостаток: Включает стек сетевых протоколовизпередача инфекции,по сравнению сместныйрозетка Там могут быть некоторыеизпередача инфекции延迟,В то же время необходимо учитывать вопросы сетевой безопасности и стабильности.

Сокеты можно в основном классифицировать по используемому протоколу. К распространенным относятся:

  • Потоковый сокет: также известный как SOCK_STREAM,на основе TCP протокол. Предлагает ориентированный на соединениеиз、надежныйизданныепередача инфекции,Убедитесь, что данные доходят до места назначения в порядке,И не потеряно и не повторено.
  • Датаграммный сокет: также известный как SOCK_DGRAM,на основе UDP протокол. это обеспечивает Нет связиизданныепередача инфекции服务,Пакеты могут быть потеряны и дублированы.,Порядок данных не гарантируется.
  • Необработанная розетка: Обеспечивает прямой доступ к базовым сетевым протоколам, таким как ICMP (для сообщения об ошибках сети и диагностики), IGMP (Интернет- Соглашение об управлении группой) и т. д. Обычно для использования требуются специальные разрешения.

существовать UNIX и категория UNIX в системе,розеткав целомиспользоватьнижесистемный вызовруководитьсоздавать、обязательность、монитор、соединять、Такие операции, как отправка и получение данных:

  • socket() Создает сокет, возвращающий дескриптор файла.
  • bind() Привяжите сокет к адресу, например IP Адрес и номер порта.
  • listen() Только для использования с потоковыми сокетами: помечает сокет как пассивный, ожидающий запросов на соединение.
  • accept() толькоиспользуется дляпотокрозетка,Принять запрос на соединение от клиента,Возвращает новый дескриптор файла для связи с клиентом.
  • connect() толькоиспользуется дляпотокрозетка,соединятьудаленнорозетка(клиент)。
  • send() и recv() Отправка и получение данных.
  • sendto() и recvfrom() используется дляданные报розетка,Отправка и получение датаграмм.

Пример кода для базовой связи клиент-сервер с использованием сокетов:

серверная часть (server.c)

Язык кода:javascript
копировать
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>

#define PORT 8888

int main() {
    int server_fd, new_socket;
    struct sockaddr_in address;
    int addrlen = sizeof(address);
    char buffer[1024] = {0};
    const char *hello = "Hello from server";

    // создавать TCP розетка
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
        perror("Socket creation failed");
        exit(EXIT_FAILURE);
    }

    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(PORT);

    // Волярозеткаобязательность по указанному адресу и порту
    if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
        perror("Bind failed");
        exit(EXIT_FAILURE);
    }

    // Слушайте входящие запросы на подключение
    if (listen(server_fd, 3) < 0) {
        perror("Listen failed");
        exit(EXIT_FAILURE);
    }

    // Принимайте соединения и обрабатывайте данные
    if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
        perror("Accept failed");
        exit(EXIT_FAILURE);
    }

    // Получить данные от клиента и отправить ответ
    int valread = read(new_socket, buffer, 1024);
    printf("Received message from client: %s
", buffer);
    send(new_socket, hello, strlen(hello), 0);
    printf("Hello message sent
");

    return 0;
}

клиент (client.c)

Язык кода:javascript
копировать
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>

#define PORT 8888

int main() {
    int sock = 0;
    struct sockaddr_in serv_addr;
    char *hello = "Hello from client";
    char buffer[1024] = {0};

    // создавать TCP розетка
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        perror("Socket creation failed");
        exit(EXIT_FAILURE);
    }

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(PORT);

    // Воля IPv4 Преобразование адреса из текстового в двоичный формат
    if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) {
        perror("Invalid address/ Address not supported");
        exit(EXIT_FAILURE);
    }

    // Подключиться к серверу
    if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
        perror("Connection failed");
        exit(EXIT_FAILURE);
    }

    // Отправить сообщение на сервер
    send(sock, hello, strlen(hello), 0);
    printf("Hello message sent to server
");

    // Получить ответ сервера
    int valread = read(sock, buffer, 1024);
    printf("Message from server: %s", buffer);

    return 0;
}

3.6. Файлы, отображаемые в памяти.

Файлы, отображаемые в памяти (Memory-Mapped Files) — это эффективный способ доступа к файлам.,этопозволять Воля一个документиз内容直接映射到процессиз虚拟内жить空间середина,Это делает чтение и запись файлов столь же эффективными, как и доступ к памяти.

Рабочий механизм:

  1. Создание карт: вызов процесса mmap() системный вызов,просить Воля一个документизчастьили Весь контент отображается сам на себяизвиртуальное адресное пространство。mmap() Параметры функции включают дескриптор файла, длину сопоставления, разрешения (чтение, запись, выполнение), флаг сопоставления и т. д.
  2. Отображение виртуальной памяти: Операционная системасуществоватьпроцессизвиртуальное адресное пространствосерединасоздавать一段与документ对应из虚拟内жить区домен,Называется областью отображения памяти. Эта область виртуальной памяти может соответствовать части файла или всему содержимому файла.,Зависит от длины, указанной при сопоставлении.
  3. Сопоставление таблицы страниц: Операционная системапроходитьтаблица страниц Воля Область виртуальной памяти, сопоставленная с реальной физической памятью.или ВОЗ交换空间середина。Начальное время,Страницы в областях виртуальной памяти могут не иметь реальных страниц физической памяти.,Вместо этого он указывает на данные в соответствующем месте файла.
  4. Доступ к файлу: Когда процесс обращается к области, отображенной в памяти, и если данные еще не загружены в физическую память, операционная система считывает соответствующую часть данных в файле на страницу в физической памяти. Таким образом, процесс может читать и записывать содержимое файла, читая и записывая область, отображенную в памяти.
  5. Синхронизация и обновление: Изменения отображенных в памяти файлов напрямую повлияют на содержимое соответствующих файлов. Даже если содержимое файла будет изменено, оно будет отражено в памяти. Операционная система обеспечивает msync() Функция для синхронизации изменения отображаемой области памяти с файлом или совместного использования измененных данных между различными процессами.
  6. Сопоставление релизов: Когда файл, отображаемый в памяти, больше не нужен, процесс может вызвать munmap() Когда функция освобождает сопоставление, операционная система отменяет отношение сопоставления в виртуальном адресном пространстве и при необходимости обновляет изменения файлов на диске.

Ключевые особенности:

  • Эффективный доступ: файл, отображенный в памятипозволять直接Воля Содержимое файла отображается в памяти,Позволяет избежать накладных расходов на производительность, связанных с традиционными системными вызовами чтения и записи.,Повышена эффективность доступа к файлам.
  • Поделиться файлами: Несколько процессов могут отображать один и тот же файл в свои адресные пространства для совместного использования содержимого файла.
  • Прозрачность: Операции доступа к областям, отображаемым в памяти, выглядят как операции с памятью, что более удобно и интуитивно понятно для программистов.
  • Живые обновления: файл, отображенный в памятииз Исправлять Может即时反映到документ本身,или совместно с другими процессами,Никаких дополнительных операций чтения и записи файлов не требуется.

Сценарии применения:

  • Система базы данных: База данных может использовать файлы, отображаемые в памяти, для непосредственной работы с файлами данных, повышая производительность чтения и записи.
  • Редактор файлов: Текстовый редактор может использовать файлы, отображенные в памяти, для обработки больших файлов, поддерживая операции быстрого поиска и изменения.
  • Мультимедийная обработка: Мультимедийные приложения могут использовать файлы, отображаемые в памяти, для чтения и записи больших файлов, таких как аудио- и видеофайлы.
  • Общая память: При обмене данными между процессами для передачи данных можно использовать файлы, отображаемые в общей памяти, чтобы повысить эффективность связи.

4. Резюме

межпроцессное взаимодействие (IPC) как важная часть современных вычислительных систем,Играет ключевую роль в обеспечении бесперебойного многопроцессного сотрудничества. Эта статья начинается с основных концепций IPC.,Углубленное обсуждение принципов, преимуществ и недостатков, а также сценариев практического применения различных классических и продвинутых IPC.

IPCдасуществоватьмногопроцессныйсредасерединавыполнитьмежпроцессное ключевые технологии взаимодействия с участием Обмена данными、координация задачиобновление статусаждатьмногие аспекты。эффективныйизIPCмеханизм Можетулучшить системупроизводительностьи Скорость ответа,Обеспечьте согласованность данных и безопасность,Это незаменимая часть современных вычислительных систем.

Учебные книги:

  • 《Unix Network Programming, Volume 2: Interprocess Communications》 :классическийизUNIXОдна из серий сетевого программирования.,Подробное объяснение различных механизмов IPC.,особенныйдарозетка иUNIXдоменрозеткаждатьсетьIPCСпособ。
  • 《Advanced Programming in the UNIX Environment》 : еще одна классическая книга по программированию UNIX, в которой подробно описываются все аспекты системного программирования UNIX, включая механизм IPC.
  • 《Linux System Programming: Talking Directly to the Kernel and C Library》 : Технические книги, посвященные системному программированию Linux, включая подробные объяснения IPC, обработки сигналов, общей памяти и т. д.

boy illustration
Учебное пособие по Jetpack Compose для начинающих, базовые элементы управления и макет
boy illustration
Код js веб-страницы, фон частицы, код спецэффектов
boy illustration
【новый! Суперподробное】Полное руководство по свойствам компонентов Figma.
boy illustration
🎉Обязательно к прочтению новичкам: полное руководство по написанию мини-программ WeChat с использованием программного обеспечения Cursor.
boy illustration
[Забавный проект Docker] VoceChat — еще одно приложение для мгновенного чата (IM)! Может быть встроен в любую веб-страницу!
boy illustration
Как реализовать переход по странице в HTML (html переходит на указанную страницу)
boy illustration
Как решить проблему зависания и низкой скорости при установке зависимостей с помощью npm. Существуют ли доступные источники npm, которые могут решить эту проблему?
boy illustration
Серия From Zero to Fun: Uni-App WeChat Payment Practice WeChat авторизует вход в систему и украшает страницу заказа, создает интерфейс заказа и инициирует запрос заказа
boy illustration
Серия uni-app: uni.navigateЧтобы передать скачок значения
boy illustration
Апплет WeChat настраивает верхнюю панель навигации и адаптируется к различным моделям.
boy illustration
JS-время конвертации
boy illustration
Обеспечьте бесперебойную работу ChromeDriver 125: советы по решению проблемы chromedriver.exe не найдены
boy illustration
Поле комментария, щелчок мышью, специальные эффекты, js-код
boy illustration
Объект массива перемещения объекта JS
boy illustration
Как открыть разрешение на позиционирование апплета WeChat_Как использовать WeChat для определения местонахождения друзей
boy illustration
Я даю вам два набора из 18 простых в использовании фонов холста Power BI, так что вам больше не придется возиться с цветами!
boy illustration
Получить текущее время в js_Как динамически отображать дату и время в js
boy illustration
Вам необходимо изучить сочетания клавиш vsCode для форматирования и организации кода, чтобы вам больше не приходилось настраивать формат вручную.
boy illustration
У ChatGPT большое обновление. Всего за 45 минут пресс-конференция показывает, что OpenAI сделал еще один шаг вперед.
boy illustration
Copilot облачной разработки — упрощение разработки
boy illustration
Микросборка xChatGPT с низким кодом, создание апплета чат-бота с искусственным интеллектом за пять шагов
boy illustration
CUDA Out of Memory: идеальное решение проблемы нехватки памяти CUDA
boy illustration
Анализ кластеризации отдельных ячеек, который должен освоить каждый&MarkerгенетическийВизуализация
boy illustration
vLLM: мощный инструмент для ускорения вывода ИИ
boy illustration
CodeGeeX: мощный инструмент генерации кода искусственного интеллекта, который можно использовать бесплатно в дополнение к второму пилоту.
boy illustration
Машинное обучение Реальный бой LightGBM + настройка параметров случайного поиска: точность 96,67%
boy illustration
Бесшовная интеграция, мгновенный интеллект [1]: платформа больших моделей Dify-LLM, интеграция без кодирования и встраивание в сторонние системы, более 42 тысяч звезд, чтобы стать свидетелями эксклюзивных интеллектуальных решений.
boy illustration
LM Studio для создания локальных больших моделей
boy illustration
Как определить количество слоев и нейронов скрытых слоев нейронной сети?
boy illustration
[Отслеживание целей] Подробное объяснение ByteTrack и детали кода