------------------------------------------
#! /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]