[[ header START ]]

Welcome to OS2.GURU site! (eComStation.RU)

Select your language: Russian English Deutch Spanish Italian Portuguese Czech Polish French

Frequently asked questions and answers:
telegram

Форум обсуждение

telegram

Send message

telegram

[ +7-981-8529467 (Санкт-Петербург)

telegram

t.me/os2_guru

eComStation.RU


ru · en · de · es · it · pt · cz · pl · fr
OS/2 - это совершенно другая операционная система для PC (ArcaOS, eComStation, IBM OS/2 Warp)
Программы, новости, статьи, поддержка пользователей, оборудование, вопросы и ответы.
 
[Что такое OS/2?  Новости  Установка  Обновление  
 
 
Применение  Будущее  Сообщество  Проекты  

eCo Software
не получает вознаграждение
из США

[Как заработать в OS/2?

Как купить OS/2 дискету?

Идеи для фанатов OS/2

*

 
Обновление

 
Программы

 
(Санкт-Петербург)

 
Преимущества (1)

 
Разработчику (1)

 
(Пайпы программ)

 
Компании: (1)

 
История (1):

 
(Бонусы)

 
Советы:

 
(Барьеры и решения)

 
Технологии: (1)

 
(Применение в науке, лаборатории, ..)

 

 
Готовые решения:

 
Новая eComStation:

 
Будущее: (1)

 
(Ссылки на другие сайты)

 
(Картинка дня)

 
Артефакты OS/2

 
Гаджеты

Обновите ArcaOS до уровня NeoWPS

  • Установите набор PNG иконок, нарисованных дизайнером, специализирующемся на оформлении OS/2
  • Установите eSchemes 2018, чтобы менять цвета и кнопки на рабочем столе

Взаимодействие между процессами


TITLE: Взаимодействие между процессами

DATE: 2012-08-11 17:56:09

AUTHOR: Capricorn

Введение

Любой программист, который пишет софт для многозадачной OS (а в наши дни других фактически не существует) рано или поздно сталкивается с необходимостью обеспечить взаимодействие между несколькими программами, которые должны работать в связке. В OS/2 для этой цели существует несколько механизмов: семафоры, пайпы, общая (разделяемая) память, очереди. Если с первыми двумя всё более-менее понятно и программисты активно используют их, то очереди и общая память почему-то обделены вниманием. На мой взгляд, совершенно незаслуженно. Цель данной статьи - подробно рассмотреть данные механизмы и дать рекомендации по их использованию. Но сначала, рассмотрим первые два.

Семафоры

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

а) Семафор типа "event" ("событие") нужен для того, чтобы позволить одному треду дождаться, пока другой тред выполнит некоторую задачу.

Пример:

/*************/
/*           */
/* Процесс 1 */
/*           */
/*************/

#define INCL_DOS
#include 

PSZ  szSemName  = "\\SEM32\\EVENT"; /* Имя семафора. Должно иметь префикс \SEM32\ */
HEV  hevEvent1  = 0;                /* Дескриптор семафора */

if (DosCreateEventSem(szSemName,    /* Имя создаваемого семафора  */
                    &hevEvent1,     /* Сюда будет возвращён дескриптор семафора */
                    DC_SEM_SHARED,  /* Разделяемый семафор */
                    FALSE))         /* Создаём семафор в сброшенном (занятом) состоянии */
   return 1;  /* Семафор создать не удалось */

/* Тут что-то делаем 
   До этого момента другой тред будет ждать
   срабатывания (освобождения) семафора */

DosPostEventSem(hevEvent); /* Командуем семафору сработать (освободиться) */
  
/* Продолжаем работу */

DosCloseEventSem(hevEvent1);      /* Избавляемся от семафора */

 

/*************/
/*           */
/* Процесс 2 */
/*           */
/*************/


Трубы (pipes)

[дополнение]

Разделяемая память

[дополнение]

Очереди

Ещё один способ взаимодействия между процессами - очереди (queues). Как уже говорилось ранее, очереди почему-то обойдены вниманием в пользу труб (pipes). На мой взгляд, совершенно незаслуженно. Очень часто очереди оказываются намного удобнее. Но, всё по-порядку.

Итак, очередь представляет собой механизм обмена сообщениями. Они чем-то напоминают очереди сообщений Presentation Manager'а, но есть существенные различия, поэтому не стоит их путать. Главное различие состоит в том, что не смотря на название, очереди могут работать не только в режиме собственно, очередей (FIFO), но и в режиме стека (LIFO), а также, по приоритетам.

Очереди всегда именованные.

Чаще всего, один процесс (тред), который мы условно назовём сервером, создаёт очередь и слушает его, другие (назовём их клиентами), открывают её и пишут туда сообщения. Разумеется, для прослушивани очереди логично организовать цикл.

Пример:

/**********************/
/*                    */
/* Процесс 1 (сервер) */
/*                    */
/**********************/

#define INCL_DOS
#include 

#define QUEUE_FIFO 0	// Очередь
#define QUEUE_LIFO 1	// Стек
#define QUEUE_PRIO 2	// По приоритетам

#define MSG_QUIT   0x0001 /* Идентификатор сообщения для завершения цикла */

#define QUEUE_NAME "\\QUEUES\\special.que"	/* Имя очереди.
						 * Должно иметь префикс \QUEUES\
						 */

/* Функция, которая будет обрабатывать сообщения */
BOOL processMessage(ULONG ulMessageId, ULONG ulDataSize, PVOID pvData);

int main(void)
{
	HQUEUE hQueue;	/* Сюда будет помещён хэндл очереди */
	APIRET rc;	/* Результат вызова функций API */	

	/* Открываем очередь */
	rc = DosCreateQueue(&hQueue, QUEUE_FIFO, QUE_NAME);
	if (rc)
		return rc;
		
	/* Цикл обработки сообщений из очереди */	
	while(TRUE)
	{
		REQUESTDATA requestData;        /* Структура для помещения данных запроса */
		ULONG       ulDataSize;         /* Сюда будет помещён объём присланных данных */
		PVOID       pvData;             /* Сюда будет помещена ссылка на присланные данные */
		rc = DosReadQueue(hQueue,       /* Хэндл очереди */
                                 &requestData, /* Данные запроса */
                                 &ulDataSize,  /* Объём присланных данных */
                                 &pvData,      /* Присланные данные */
                                 0,            /* Читаем первый элемент из очереди */
                                 FALSE,        /* Ждём */
                                 0,            /* Приоритет  не нужен */
                                 NULLHANDLE);  /* Нэндл семафора-собатия  не нужен */
		if (rc || requestData.ulData==MSG_QUIT)
			break;
		processMessage(ulMessageId, ulDataSize, pvData);
	}
	rc = DosCloseQueue(hQueue);             /* Удаляем очередь */
	return rc;
}

 

/**********************/
/*                    */
/* Процесс 2 (клиент) */
/*                    */
/**********************/

#define MSG_QUIT   0x0001 /* Идентификатор сообщения для завершения цикла */

#define QUEUE_NAME "\\QUEUES\\special.que"	/* Имя очереди.
						 * Должно иметь префикс \QUEUES\
#define INCL_DOS
#include 

int main(void)
{
	HQUEUE hQueue;	/* Сюда будет помещён хэндл очереди */
	APIRET rc;	/* Результат вызова функций API */	
	PID	pid;	/* Идентификатор процесса, создавшего очередь */

	/* Открываем очередь */
	rc = DosOpenQueue(&pid, &hQueue, QUE_NAME);
	if (rc)
		return rc;

	rc = DosWriteQueue(hQueue, MSG_QUIT, 0L, NULL, 0L); /* Записываем в очередь сообщение*/
	rc = DosCloseQueue(hQueue);                         /* Закрываем очередь */
	return rc;
}

В данном примере мы первый процесс создаёт и слушает очередь. Другой процесс открывает очередь и записывает туда определённое нами сообщение о завершении работы (MSG_QUIT). Первый процесс, получив это сообщение, завершает свою работу.

Обратите внимание, что функция DosCloseQueue() по сути, удаляет хэндл очереди. Как только все хэндлы очереди будут удалены, удалится и сама очередь.

Так в чём же преимущество очередей перед трубами? Дело в том, что при использовании труб мы фактически имеем дело с непрерывным потоком данных. Это удобно, когда необходимо постоянно передавать большие объёмы данных. Но такие случаи очень редки. Чаще бывает нужно, чтобы один процесс сообщал другому о неких событиях или передавал какие-то команды, на которые другой процесс должен реагировать. В данном случае очереди гораздо удобнее, т. к. сообщение, помещённое в очередь как раз и является такой командой.

 

Попробуй программу:

Panorama VESA - быстрый видеодрайвер для многопроцессорных компьютеров.

Комментарии:

Прокомментируйте эту статью (напоминаем, автор работал над текстом несколько недель, уважайте мнение других).


Ваше имя:

Ваш E-Mail:

CODE:
......

  

Ваш комментарий:


Как избежать потерю данных? a) не пользуйтесь старой версией JFS драйвера. b) Не пользуйтесь старым eCS CD1 (Если все-таки загружаете eCS 2.0 CD1, то откажитесь от его disk checker'а, т.к. он может повредить тома), Простые советы по сохранению JFS

Статьи

Операционная система
Программное обеспечение
Оборудование
Для разработчика
Разное
Колонка редактора


Готовая eComStation на SSD диске

 





Последний активный опрос: Какая высота барьера RPM?

[Google]

IBM OS/2 Warp

 
Обучение новичков

Списки протестированного OS/2 оборудования

 
Статьи


   
  Почему eComStation?
Возможности
Особенности
Применение
Ролики и скриншоты
   eComStation для
для бизнесменов
для студентов и инженеров
для продавцов компьютеров
сообщество пользователей
   Разработчик
Распространить программу
Описание API, библиотеки
Начать новый проект
Конкурсы
   Программы
Он-лайн каталог
Выбрать через eCo Market
   Служба поддержки
Отправить вопрос
Купить eComStation
Вопросы и ответы
Обучение новичков
 
 
© 2001 - 2021 eCo Software, All rights reserved
Сибирский Медведь технологическая компания
eComStation Serenity Systems International • OS/2 Warp IBM Corporation • ArcaOS Arca Noae