Рубрики

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

Предварительное условие: обработка сигналов C , IPC через разделяемую память

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

1. Сигнал генерируется появлением определенного события.

2. Генерируемый сигнал доставляется конкретному процессу.

3. Сигнал должен быть обработан после получения в процессе.

В этой проблеме сообщение отправляется от одного пользователя другому пользователю с помощью функции kill . Функция kill принимает два входа — идентификатор процесса процесса получателя и тип сигнала. Для этой цели мы используем разделяемую память, в которой хранятся идентификаторы процессов двух процессов. Мы используем функцию- обработчик, которая печатает сообщение, полученное от другого процесса. Пользователь2 начнет отправлять сообщение Пользователю1, а затем они продолжат общаться.

Пользователь 1

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

  
#define FILLED 0
#define Ready 1
#define NotReady -1

  

struct memory {

    char buff[100];

    int status, pid1, pid2;

};

  

struct memory* shmptr;

  
// функция-обработчик для печати сообщения, полученного от user2

  

void handler(int signum)

{

    // если signum SIGUSR1, то пользователь 1 получает сообщение от user2

  

    if (signum == SIGUSR1) {

        printf("Received User2: ");

        puts(shmptr->buff);

    }

}

  

int main()

{

    // идентификатор процесса user1

  

    int pid = getpid();

  

    int shmid;

  

    // значение ключа разделяемой памяти

    int key = 12345;

  

    // создание общей памяти

    shmid = shmget(key, sizeof(struct memory), IPC_CREAT | 0666);

  

    // прикрепляем разделяемую память

  

    shmptr = (struct memory*)shmat(shmid, NULL, 0);

  

    // сохраняем идентификатор процесса user1 в разделяемой памяти

    shmptr->pid1 = pid;

    shmptr->status = NotReady;

  

    // вызов функции сигнала с использованием типа сигнала SIGUSER1

    signal(SIGUSR1, handler);

  

    while (1) {

        while (shmptr->status != Ready)

            continue;

        sleep(1);

  

        // принимаем данные от user1

  

        printf("User1: ");

        fgets(shmptr->buff, 100, stdin);

  

        shmptr->status = FILLED;

  

        // отправляем сообщение пользователю user2 с помощью функции kill

  

        kill(shmptr->pid2, SIGUSR2);

    }

  

    shmdt((void*)shmptr);

    shmctl(shmid, IPC_RMID, NULL);

    return 0;

}

Пользователь 2

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

  
#define FILLED 0
#define Ready 1
#define NotReady -1

  

struct memory {

    char buff[100];

    int status, pid1, pid2;

};

  

struct memory* shmptr;

  
// функция-обработчик для печати сообщения, полученного от user1

  

void handler(int signum)

{

    // если signum SIGUSR2, то пользователь 2 получает сообщение от user1

  

    if (signum == SIGUSR2) {

        printf("Received From User1: ");

        puts(shmptr->buff);

    }

}

  
// основная функция

  

int main()

{

    // идентификатор процесса user2

    int pid = getpid();

  

    int shmid;

  

    // значение ключа разделяемой памяти

    int key = 12345;

  

    // создание общей памяти

  

    shmid = shmget(key, sizeof(struct memory), IPC_CREAT | 0666);

  

    // прикрепляем разделяемую память

  

    shmptr = (struct memory*)shmat(shmid, NULL, 0);

  

    // сохраняем идентификатор процесса user2 в разделяемой памяти

    shmptr->pid2 = pid;

  

    shmptr->status = NotReady;

  

    // вызов функции сигнала с использованием типа сигнала SIGUSR2

    signal(SIGUSR2, handler);

  

    while (1) {

        sleep(1);

  

        // принимаем данные от user2

  

        printf("User2: ");

        fgets(shmptr->buff, 100, stdin);

        shmptr->status = Ready;

  

        // отправляем сообщение пользователю user1 с помощью функции kill

  

        kill(shmptr->pid1, SIGUSR1);

  

        while (shmptr->status == Ready)

            continue;

    }

  

    shmdt((void*)shmptr);

    return 0;

}


Выход:

Рекомендуемые посты:

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

0.00 (0%) 0 votes