Welcome to eComStation.RU site!

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

Frequently asked questions and answers:

eComStation.RU

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

 
 
Отчет: OS/2 совместимое оборудование
Как получить драйверы OS/2 бесплатно

 
Обновление

 
Программы

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

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

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

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

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

 
История (1):

 
(Бонусы)

 
Советы:

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

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

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

 

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

 
Новая eComStation:

 
Будущее: (1)

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

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

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

 
Гаджеты

 

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


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:
......

  

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


eComStation - реактивная система, удобная для работы. Вытесняющая многозадачность + поддержка многопроцессорности с 1994 года + Большинство программ используют многопоточность.

Статьи

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


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

 





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

IBM OS/2 Warp

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

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

 
Статьи


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

 

 
Картинка дня: