2014-12-09 5 views
6

Возможно, мне просто не хватает чего-то очевидного в API System.Process (http://hackage.haskell.org/package/process), но, похоже, он не поддерживает получение исходного PID созданного процесса. API обычно возвращает ProcessHandle, который можно использовать достаточно легко, но это, похоже, не соответствует потребностям развертывания, которые у меня есть.Как получить идентификатор процесса созданного процесса в Haskell?

У меня есть случай, когда я хочу запустить длительный процесс, зарегистрировать PID, который он использует, и иметь возможность автоматически возвращаться в более позднее время (дни, недели, месяцы) и убивать старый процесс и повторно -START с новым процессом. Я уверен, что есть несколько способов сделать это автоматически развернуть и перезапустить, но PID выглядели как самый простой способ сделать это без слишком большого кода, зависящего от платформы.

Я открыт для других предложений по моей основной проблеме, но мне кажется странным, что я не могу найти прямых ссылок PID (или способ их преобразования в API процесса). Это похоже на контроль API.

+0

Можете ли вы использовать пакет '' unix' '(http://hackage.haskell.org/package/unix-2.7.0.1/docs/System-Posix-Process.html) вместо 'process'? –

+0

... или ['Win32'] (http://hackage.haskell.org/package/Win32-2.2.2.0/docs/System-Win32-Process.html). Общий момент заключается в том, что API-интерфейсы, специфичные для ОС, обычно более мощные, чем кросс-платформенные, поскольку кросс-платформенные могут поддерживать только те вещи, которые поддерживаются всеми ОС. –

+0

Правда, API-специфичные API, как правило, более мощные. Но, это немного раздражает, когда _one_ вещь останавливает ваш код от полной переносимости. – stormont

ответ

4

Вот несколько примеров кода:

import System.Process 
import System.Process.Internals 

-- | returns Just pid or Nothing if process has already exited 
getPid ph = withProcessHandle ph go 
    where 
    go ph_ = case ph_ of 
       OpenHandle x -> return $ Just x 
       ClosedHandle _ -> return Nothing 

main = do 
    (_,_,_,ph) <- createProcess $ shell "echo $$" 
    getPid ph >>= print 

Примечание: I убежище 't тестировал это под Windows, но он работает на OSX и, предположительно, на Linux.

для Windows, то Win32 package имеет getProcessId функцию в модуле System.Win32.Process, и в соответствии с кодом, я прочитал, что это должно работать:

import System.Win32.Process (getProcessId) 

main = do 
    (_,_,_,ph) <- createProcess $ shell "echo $$" 
    pid <- withProcessHandle ph go 
    print pid 

    where go (OpenHandle x) = fmap Just $ getProcessId x 
     go (ClosedHandle _) = return Nothing 

код я обосновывая это код для interruptProcessGroupOf(link)

+0

Это, кажется, делает трюк разумным способом (также проверяется под Windows), не нарушая при этом абстракции (IMO). Это также похоже на эту старую почтовую рассылку: https://www.haskell.org/pipermail/haskell-cafe/2012-October/104028.html – stormont

+0

После дальнейшего рассмотрения я не уверен в результатах. Я изменил это на $ shell «блокнот», чтобы легче находить PID в диспетчере задач. Похоже, я получаю разные PID для этого и предложения asjo, ни того, что соответствует. – stormont

+0

Скретч, я смутил себя. Я искал PID записной книжки, но я забыл, что это было вызвано оболочкой, поэтому я действительно должен был искать идентификатор процесса оболочки, который соответствует результату asjo. с результатамиProcessHandle не кажутся (напрямую) результатом PID в Windows; Я получаю шестнадцатеричные значения, но они слишком малы, чтобы соответствовать дочерним процессам. – stormont

0

Если все остальное терпит неудачу,

import System.Process.Internals 

, а затем выкопать внутри ProcessHandle абстракции. Вероятно, вы хотите извлечь PHANDLE из MVar.

Обратите внимание, что это разрушает уровень абстракции, который предназначен для переноса кода через ОС. Используйте его с особой осторожностью и будьте готовы к тому, чтобы он разбился на новые версии библиотеки.

3

Похоже interruptProcessGroupOf в System.Process вызовов либо System.Posix.Process.getProcessGroupIDOf (POSIX/не Windows) или System.Win32.Process.getProcessId (Windows), чтобы получить PID: http://git.haskell.org/packages/process.git/blob/HEAD:/System/Process.hs

+0

Не могли бы вы описать разницу между 'getProcessGroupID' и' getProcessID' в 'System.Posix.Process'? –

+0

Нет. Я думаю, что один работает для систем POSIX, другой для систем Windows. Я думаю, что System.Process можно было бы изменить, чтобы разложить код для получения pid из interruptProcessGroupOf в функцию, которую может использовать код с использованием System.Process. – asjo

+0

Я был немного неясен. Обе функции, о которых я упоминал, находятся в модуле 'System.Posix.Process', отличном от' getProcessId' в модуле Windows. (Даже написано по-разному: 'ID' против' Id'.) Я думаю, что это имеет какое-то отношение к получению PID текущего процесса и получению PID родительского процесса, но я не понимаю деталей. –

Смежные вопросы