------------------------------------------
#! /usr/share/doc/defaced/2/tandp/port.txt
------------------------------------------
################################################################################
#
# Тема.......Портирование C/C++ приложений. Часть I.
# Управление потоками и процессами.
# Автор......black_c0de
# Группа.....[The N0b0D1eS] //[tN]
# [email protected]
# HTTP.......http://nteam.ru/
# DATE.......06.06.03
#
# Все права принадлежат [The N0b0D1eS]
#
################################################################################
Данная статья является первой из серии статей, которые будут посвящены теме
портирования приложений, написанных на C/C++, из windows -> unix и unix ->
windows. В данной статье я расскажу об аналогах функций для работы с потоками и
процессами, которые присутствуют в этих операционных системах. Далее мы, tN,
будем продолжать эту серию статей, описывая основные методы и хинты портирования
программного обеспечения.
*** Содержание ***
----------------------------
[1] Вступление;
[2] Типы программного обеспечения и относительная сложность при портировании;
[3] Функции управления процессами;
[4] Функции потоков и планирования;
[5] Функции синхронизации потоков;
[6] Функции межпроцессных взаимодействий;
[7] Нюансы при работе с процессами в Win32 и UNIX;
[8] Нюансы при работе с потоками в Win32 и UNIX;
[9] Заключение;
[10] Литература;
*** Вступление ***
--------------------------
В данный момент существуют всего два основных семейства операционных систем:
- WINDOWS
- UNIX like OS
Поэтому не удивительно, что у разработчиков программного обеспечения часто
возникает необходимость перенести код уже написанной программы на другую
операционную систему. Но, в силу различий архитектуры обсуждаемых операционных
систем, данная задача весьма не проста. Сложность работы, которую будет
необходимо проделать при портировании вашего проекта, зависит от того, к какому
типу программного обеспечения относится портируемый проект.
*** Типы программного обеспечения и относительная сложность при портировании ***
--------------------------------------------------------------------------------
Можно выделить следующие _основные_ типы программного обеспечения:
- Прикладная пользовательская программа;
- Программа для работы в сетях TCP/IP, etc;
- Системное программное обеспечение (основная часть кода - системное API);
- Системные драйверы;
Первый тип ПО портируется проще, чем все остальные. Здесь предполагается наличие
стандартных библиотечных функций, которые имеют свои аналоги в другой
операционной системе, возможно редкое использование API-функций, которые или
имеют свой аналог в другой ОС или же, при затрате некоторых усилий,
переделываются с использованием имеющихся в распоряжении системных ресурсов.
Второй тип - сетевое программное обеспечение - также как и первый тип,
портируется относительно просто. Как показывает практика, основная часть
сетевого ПО написана при использовании стандартных функций и структур данных
Berkley Sockets, то есть:
socket(), connect(), bind(), listen(), recv(), send(), sockaddr_in, и так
далее...
Последние два типа программного обеспечения вызывают определенные сложности при
портировании в силу используемых при написании архитектурно-зависимых системных
API функций.
В данной статье вы сможете почерпнуть неимоверно важный материал - аналоги
многих системно-зависимых функций для работы с потоками и процессами в
операционных системах UNIX и WINDOWS.
*** Функции управления процессами ***
-------------------------------------
+------------------------------------------------------------------------------+
| УПРАВЛЕНИЕ ПРОЦЕССАМИ |
+------------------------+-------------------+------------------+--------------+
| WINDOWS | UNIX | БИБЛИОТЕКА С | КОММЕНТАРИИ |
+------------------------+-------------------+------------------+--------------+
| CreateProcess | fork(), execl()* | нет | |
+------------------------+-------------------+------------------+--------------+
| ExitProcess | _exit | exit | |
+------------------------+-------------------+------------------+--------------+
| GetCommandLine | argv[] | нет | |
+------------------------+-------------------+------------------+--------------+
| GetCurrentProcess | getpid* | нет | |
+------------------------+-------------------+------------------+--------------+
| GetCurrentProcessId | getpid* | нет | |
+------------------------+-------------------+------------------+--------------+
| GetEnvironmentStrings | нет | нет | |
+------------------------+-------------------+------------------+--------------+
|GetEnvironmentVariables | нет | getenv | |
+------------------------+-------------------+------------------+--------------+
| GetExitCodeProcess | wait, waitpid | нет | |
+------------------------+-------------------+------------------+--------------+
| GetProcesslimes |times, wait3, wait4| нет | |
+------------------------+-------------------+------------------+--------------+
|GetProcessWorkingSetSize| wait3 ,wait4 | нет | |
+------------------------+-------------------+------------------+--------------+
| нет | execl*, execv*, | нет | в win32 нет |
| | execle*, execve*,| | точного |
| | execlp*, execvp* | | эквивалента |
+------------------------+-------------------+------------------+--------------+
| нет | fork, vfork | нет | в win32 нет |
| | | | точного |
| | | | эквивалента |
+------------------------+-------------------+------------------+--------------+
| нет | getpid | нет | в win32 нет |
| | | | отношений |
| | | | родитель- |
| | | | потомок |
+------------------------+-------------------+------------------+--------------+
| нет | getgid, getegid | нет | в win32 нет |
| | | | групп |
| | | | процессов |
+------------------------+-------------------+------------------+--------------+
| нет | getpgr | нет | |
+------------------------+-------------------+------------------+--------------+
| нет | setpgid | нет | |
+------------------------+-------------------+------------------+--------------+
| нет | setsid | нет | |
+------------------------+-------------------+------------------+--------------+
| нет | tcgetpgr | нет | |
+------------------------+-------------------+------------------+--------------+
| нет | tcsetpgr | нет | |
+------------------------+-------------------+------------------+--------------+
| OpenProcess | нет | нет | |
+------------------------+-------------------+------------------+--------------+
| SetEnvironmentVariable | putenv | нет | putenv не |
| | | | входит в |
| | | | состав |
| | | | стандартной |
| | | | библиотеки C |
+------------------------+-------------------+------------------+--------------+
| TerminateProcess | kill | нет | |
+------------------------+-------------------+------------------+--------------+
| WaitForMultipleObjects | waitpid | нет | |
+------------------------+-------------------+------------------+--------------+
| WaitForSingleObject | wait, waitpid | нет | |
+------------------------+-------------------+------------------+--------------+
| KillTimer | alarm(0) | нет | |
+------------------------+-------------------+------------------+--------------+
| SetTimer | alarm | нет | |
+------------------------+-------------------+------------------+--------------+
| Sleep | sleep | | |
+------------------------+-------------------+------------------+--------------+
| Sleep | poll или lect без | нет | |
| | дескриптора файла | | |
+------------------------+-------------------+------------------+--------------+
*** Функции потоков и планирования ***
--------------------------------------
+------------------------------------------------------------------------------+
| ПОТОКИ И ПЛАНИРОВАНИЕ |
+----------------------------------------+-------------------------------------+
| WINDOWS | UNIX / PTHREADS |
+----------------------------------------+-------------------------------------+
| CreateRemoteThread | нет |
| TlsAlloc | pthread_key_alloc |
| TlsFree | pthread_key_delete |
| TlsGetValue | pthread_getspecific |
| TlsSetValue | pthread_setspecific |
| CreateThread, _beginthreadex | pthread_create |
| ExitThread, _endthreadex | pthread_exit |
| GetCurrentThread | pthread_self |
| GetCurrentThreadId | нет |
| GetExitCodeThread | pthread_yield |
| ResumeThread | нет |
| SuspendThread | нет |
| TerminateThread | pthread_cancel |
| WaitForSingleObject | pthread_join |
| GetPriorityClass | pthread_attr_getschedpolicy |
| GetThreadPriority | pthread_attr_getschedparam |
| SetPriorityClass | pthread_attr_setschedpolicy |
| SetThreadPriority | pthread_attr_setschedparam |
+----------------------------------------+-------------------------------------+
*** Функции синхронизации потоков ***
-------------------------------------
+------------------------------------------------------------------------------+
| СИНХРОНИЗАЦИЯ ПОТОКОВ |
+-----------------------------------------+------------------------------------+
| WINDOWS | UNIX / PTHREADS |
+-----------------------------------------+------------------------------------+
| DeleteCriticalSection | используйте мьютексы для эмуляции |
| EnterCriticalSection | используйте мьютексы для эмуляции |
| InitializeCriticalSection | используйте мьютексы для эмуляции |
| LeaveCriticalSection | используйте мьютексы для эмуляции |
| CloseHandle | pthread_cond_destroy |
| CreateEvent | pthread_cond_init |
| PulseEvent | pthread_cond_signal |
| ResetEvent | нет |
| SetEvent | pthread_cond_broadcast |
| WaitForSingleObject | pthread_cond_wait |
| WaitForSingleObject | pthread_timed_wait |
| CloseHandle | pthread_mutex_destroy |
| CreateMutex | pthread_mutex_init |
| ReleaseMutex | pthread_mutex_unlock |
| WaitForSingleObject (mutex descriptor) | pthread_mutex_lock |
| CreateSemaphore | semget |
| нет | semctl |
| OpenSemaphore | semget |
| ReleaseSemaphore | semop (+) |
|WaitForSingleObject(semaphore descriptor)| semop (-) |
+-----------------------------------------+------------------------------------+
*** Функции межпроцессных взаимодействий ***
--------------------------------------------
+------------------------------------------------------------------------------+
| МЕЖПРОЦЕССНОЕ ВЗАИМОДЕЙСТВИЕ |
+--------------------------+------------------------+--------------------------+
| WINDOWS | UNIX | БИБЛИОТЕКА С |
+--------------------------+------------------------+--------------------------+
| CallNamedPipe | нет | нет |
+--------------------------+------------------------+--------------------------+
| CloseHandle | close, msgctl | pclose |
+--------------------------+------------------------+--------------------------+
| ConnectNamedPipe | нет | нет |
+--------------------------+------------------------+--------------------------+
| CreateMailslot | нет | нет |
+--------------------------+------------------------+--------------------------+
| CreatePipe | pipe | popen |
+--------------------------+------------------------+--------------------------+
| DuplicateHandle | dup, dup2, fcnfl | нет |
+--------------------------+------------------------+--------------------------+
| GetNamedPipeHandleState | stat, fstat, lstat64 | нет |
+--------------------------+------------------------+--------------------------+
| GetNamedPipeInfo | stat, fstat, lstat | нет |
+--------------------------+------------------------+--------------------------+
|ImpersonateNamedPipeClient| нет | нет |
+--------------------------+------------------------+--------------------------+
| PeekNamedPipe | нет | нет |
+--------------------------+------------------------+--------------------------+
|ReadFile(descriptor of the| | |
| named pipe ) | read(fifo), msgsnd | нет |
+--------------------------+------------------------+--------------------------+
| RevertToSelf | нет | нет |
+--------------------------+------------------------+--------------------------+
| SetNamedPipeHandleState | нет | нет |
+--------------------------+------------------------+--------------------------+
| TransactNamedPipe | нет | нет |
+--------------------------+------------------------+--------------------------+
| WriteFile(descriptor of | | |
| the named pipe) | write(fifo), msgrcv | нет |
+--------------------------+------------------------+--------------------------+
| GetComputerName | uname | нет |
+--------------------------+------------------------+--------------------------+
| SetComputerName | нет | нет |
+--------------------------+------------------------+--------------------------+
| SetNamedPipeIdentity | используйте sticky bit | нет |
+--------------------------+------------------------+--------------------------+
*** Нюансы при работе с процессами в Win32 и UNIX ***
-----------------------------------------------------
* Процессы UNIX можно сравнить с однопоточными процессами в WIN32. Сейчас
наиболее часто используется стандарт Pthreads в форме POSIX.
* Очень важным моментом является работа с функцией fork(). В Win32 нет
эквивалентна для этой функции, данную функцию достаточно сложно эмулировать в
Win32. Но если рассматривать последовательность вызовов fork() и execl() в UNIX,
которая достаточно часто используется - аналогом для этой связки есть win32
функция CreateProcess
* В windows процессы определяются дескриптором и идентификатором, в UNIX
дескрипторы отсутствуют.
*** Нюансы при работе с потоками в Win32 и UNIX ***
---------------------------------------------------
Перенесение кода, в котором используются потоки, немного сложнее нежели
перенесение кода с межпроцессными взаимодействиями. Это справедливо в том
случае, если переносится код с win32 -> UNIX и в win32 использовались
стандартные win32-API для работы с потоками: CreateThread, ResumeThread, etc...
НО! В win32 существует механизм нитей (fibers). Важнейшее применение нитей
состоит в том, что многие приложения, особенно для UNIX, написаны таким образом,
чтобы осуществлять управление потоками. Нити облегчают процесс переноса подобных
приложений в Windows NT/2000.
API нитей составляют всего шесть функций, которые обычно использются в следующем
порядке:
ConvertThreadToFiber()
CreateFiber()
SwitchToFiber()
GetFiberData()
SwitchToFiber()
.................................
ExitThread()
*** Заключение ***
------------------
Из приведенных таблиц функций видно что в операционной системе WINDOWS
разработчикам предоставлен более широкий набор методов и средств для написания
системных программ. По-моему, функции win32 имеют болеет понятные имена нежели
аналоги в UNIX, хотя разработчикам ПО для UNIX может казаться наоборот 8)
При написании данной статьи использовались некоторые данные из книги "Системное
программирование в среде WIN32, 2-е издание", Джонсон М. Харт. 2001, Addison
Wesley. ОЧЕНЬ советую эту книгу системным программистам под win32!
*** Литература ***
----------------------------
Далее следует список литературы, которая поможет при разработке системного ПО
под операционные системы семейства UNIX и WINDOWS:
1) М. Дансмур, Г. Дейвис. ОС UNIX и программирование на языке Си. - М.: Радио и
связь, 1989.
2) Р.Готье. Руководство по операционной системе UNIX. - М.: Финансы и
статистика,1986.
3) M.Bach. The design of the UNIX operating system. - Prentice Hall, Englewood
Cliffs, N.J., 1986.
4) UNIX, инструментальные средства. Джерри Пик, Тим О'Райли, Майк Лукидис, BHV
1999, O'REILLY *В этой книге очень хорошо описаны нюансы и методики
программирования на языках shell.
5) "Programming with POSIX Threads", Дэвид Бутенхоф
6) "Multithreading applications in Win32", Роберт Винер, Джим Беверидж. * Книга
полностью посвящена потокам в Win32
Если возникнут вопросы или сложности, с радостью помогу вам, пишите -
[email protected]
# all rights reserved (c) 2003 black c0de //tN [ The N0b0D1eS ] :: [ www.nteam.ru]