Elixir 1.7

Port




elixir

Port

बंदरगाहों के माध्यम से बाहरी दुनिया के साथ बातचीत के लिए कार्य।

पोर्ट्स एर्लांग वीएम के लिए बाहरी सिस्टम प्रक्रियाओं को शुरू करने के लिए एक तंत्र प्रदान करते हैं और संदेश के माध्यम से उनके साथ संवाद करते हैं।

उदाहरण

iex> port = Port.open({:spawn, "cat"}, [:binary])
iex> send(port, {self(), {:command, "hello"}})
iex> send(port, {self(), {:command, "world"}})
iex> flush()
{#Port<0.1444>, {:data, "hello"}}
{#Port<0.1444>, {:data, "world"}}
iex> send(port, {self(), :close})
:ok
iex> flush()
{#Port<0.1464>, :closed}
:ok

ऊपर दिए गए उदाहरण में, हमने एक नया पोर्ट बनाया है जो प्रोग्राम cat निष्पादित करता है। cat यूनिक्स प्रणालियों पर उपलब्ध एक कार्यक्रम है जो कई इनपुटों से डेटा प्राप्त करता है और आउटपुट में उन्हें एकत्र करता है।

पोर्ट बनने के बाद, हमने इसे Kernel.send/2 का उपयोग करते हुए संदेशों के रूप में दो कमांड भेजे। पहले कमांड में "हैलो" का बाइनरी पेलोड है और दूसरे में "दुनिया" है।

उन दो संदेशों को भेजने के बाद, हमने IEx हेल्पर flush() आह्वान किया, जिसने पोर्ट से प्राप्त सभी संदेशों को प्रिंट किया, इस मामले में हमें "हैलो" और "दुनिया" वापस मिल गई। ध्यान दें कि संदेश बाइनरी में हैं, क्योंकि हमने पास किया था :binary Port.open/2 में पोर्ट खोलने पर :binary विकल्प। इस तरह के विकल्प के बिना, यह बाइट्स की एक सूची तैयार करेगा।

एक बार सब कुछ हो जाने के बाद, हमने बंदरगाह को बंद कर दिया।

एलिक्सिर बंदरगाहों और कुछ कमियों के साथ काम करने के लिए कई उपयुक्तताएं प्रदान करता है। हम नीचे उन का पता लगाएंगे।

संदेश और फ़ंक्शन API

बंदरगाहों के साथ काम करने के लिए दो एपीआई हैं। यह संदेश पासिंग के माध्यम से या तो एसिंक्रोनस हो सकता है, जैसा कि ऊपर दिए गए उदाहरण में, या इस मॉड्यूल पर फ़ंक्शन को कॉल करके।

बंदरगाहों और उनके समकक्ष फ़ंक्शन API द्वारा समर्थित संदेशों को नीचे सूचीबद्ध किया गया है:

  • {pid, {:command, binary}} - दिए गए डेटा को पोर्ट में भेजता है। command/3 देखें।

  • {pid, :close} - पोर्ट को बंद करता है। जब तक कि पोर्ट पहले से ही बंद नहीं हो जाता, तब तक पोर्ट अपने बफ़र्स को फ्लश करने और प्रभावी रूप से बंद होने के बाद {port, :closed} संदेश के साथ जवाब देगा। close/1 देखें।

  • {pid, {:connect, new_pid}} - new_pid को पोर्ट के नए मालिक के रूप में सेट करता है। एक बार पोर्ट को खोलने के बाद, पोर्ट को लिंक किया जाता है और कॉलर प्रक्रिया से जुड़ा होता है और पोर्ट से संचार केवल कनेक्टेड प्रक्रिया से होता है। यह संदेश नए जुड़े हुए प्रक्रियाओं को new_pid बनाता है। जब तक पोर्ट मर नहीं जाता, पोर्ट पुराने मालिक को {port, :connected} साथ जवाब देगा। connect/2 देखें connect/2

अपनी बारी पर, पोर्ट निम्नलिखित प्रक्रिया को निम्नलिखित संदेश भेजेगा:

  • {port, {:data, data}} - पोर्ट द्वारा भेजा गया डेटा
  • {port, :closed} - {pid, :close} संदेश का उत्तर दें
  • {port, :connected} - {pid, {:connect, new_pid}} संदेश का उत्तर दें
  • {:EXIT, port, reason} - पोर्ट क्रैश होने की स्थिति में एग्जिट सिग्नल। यदि कारण नहीं है :normal , यह संदेश केवल तभी प्राप्त होगा जब स्वामी प्रक्रिया बाहर निकल रही है

खुला तंत्र

पोर्ट को चार मुख्य तंत्रों के माध्यम से खोला जा सकता है।

एक संक्षिप्त सारांश के रूप में, नीचे दिए गए :spawn और :spawn_executable विकल्पों का उपयोग करना पसंद करते हैं। वीएम के भीतर उन्नत उपयोग के लिए अन्य दो विकल्प :spawn_driver और :fd हैं। इसके अलावा System.cmd/3 का उपयोग करने पर विचार करें, यदि आप चाहते हैं कि किसी प्रोग्राम को निष्पादित किया जाए और उसका रिटर्न मान पुनः प्राप्त किया जाए।

अंडे

:spawn ट्यूपल एक बाइनरी प्राप्त करता है जिसे पूर्ण आहरण के रूप में निष्पादित किया जा रहा है। उदाहरण के लिए, हम इसका उपयोग सीधे "इको हेलो" आह्वान करने के लिए कर सकते हैं:

iex> port = Port.open({:spawn, "echo hello"}, [:binary])
iex> flush()
{#Port<0.1444>, {:data, "hello\n"}}

:spawn तर्क से प्रोग्राम का नाम पुनः प्राप्त करेगा और आपके OS $PATH पर्यावरण चर को एक मेल खाते प्रोग्राम की तलाश करेगा।

यद्यपि उपरोक्त कार्य आसान है, इसका मतलब है कि एक निष्पादन योग्य को लागू करना असंभव है जिसके नाम पर व्हाट्सएप है या इसके किसी भी तर्क में। उन कारणों के लिए, ज्यादातर बार इसे निष्पादित करना बेहतर होता है :spawn_executable

spawn_executable

स्पॉन निष्पादन योग्य स्पॉन का अधिक प्रतिबंधित और स्पष्ट संस्करण है। यह पूर्ण फ़ाइल पथ निष्पादन योग्य आप निष्पादित करना चाहते हैं की उम्मीद है। यदि वे आपके $PATH , तो उन्हें System.find_executable/1 : कहकर पुनः प्राप्त किया जा सकता है।

iex> path = System.find_executable("echo")
iex> port = Port.open({:spawn_executable, path}, [:binary, args: ["hello world"]])
iex> flush()
{#Port<0.1380>, {:data, "hello world\n"}}

उपयोग करते समय :spawn_executable , तर्कों की सूची को निम्न के माध्यम से पास किया जा सकता है :args विकल्प। विकल्पों की पूरी सूची के लिए, Erlang फ़ंक्शन के लिए दस्तावेज़ देखें :erlang.open_port/2

fd

:fd नाम विकल्प डेवलपर्स को एर्लैंग वीएम द्वारा उपयोग किए out फ़ाइल डिस्क्रिप्टर in प्रवेश करने की अनुमति देता है। यदि आप रनटाइम सिस्टम के मुख्य भाग को फिर से लागू कर रहे हैं, जैसे :user :shell और :shell प्रक्रियाएँ।

ज़ोंबी ओएस प्रक्रियाओं

कोई पोर्ट close/1 फ़ंक्शन के माध्यम से या {pid, :close} संदेश भेजकर बंद किया जा सकता है। हालाँकि, यदि VM क्रैश हो जाता है, तो पोर्ट द्वारा शुरू किया गया एक लंबे समय तक चलने वाला प्रोग्राम इसकी स्टडिन और स्टडआउट चैनल बंद हो जाएगा, लेकिन यह स्वचालित रूप से समाप्त नहीं होगा

जबकि अधिकांश UNIX कमांड लाइन टूल एक बार इसके संचार चैनल बंद हो जाने के बाद बाहर निकल जाएंगे, लेकिन सभी कमांड लाइन एप्लिकेशन ऐसा नहीं करेंगे। जबकि हम यह पता लगाकर सुशोभित समाप्ति को प्रोत्साहित करते हैं कि यदि स्टड / स्टडआउट को बंद कर दिया गया है, तो हमारे पास हमेशा यह नियंत्रण नहीं होता है कि तीसरा पक्ष सॉफ़्टवेयर कैसे समाप्त होता है। उन मामलों में, आप एप्लिकेशन को एक स्क्रिप्ट में लपेट सकते हैं जो स्टड के लिए जांच करता है। यहाँ इस तरह की पटकथा है:

#!/bin/sh
"[email protected]" &
pid=$!
while read line ; do
  :
done
kill -KILL $pid

अब इसके बजाय:

Port.open({:spawn_executable, "/path/to/program"},
          [args: ["a", "b", "c"]])

आप चालान कर सकते हैं:

Port.open({:spawn_executable, "/path/to/wrapper"},
          [args: ["/path/to/program", "a", "b", "c"]])

सारांश

प्रकार

name()

कार्य

close/1

port बंद कर देता port

command/3

पोर्ट ड्राइवर port लिए data भेजता है

connect/2

port पहचानकर्ता को एक pid साथ pid

डेमनीटर (मॉनिटर_ क्रोम, विकल्प \\ [])

मॉनिटर दिए गए reference द्वारा पहचाने गए मॉनिटर

info(port)

यदि पोर्ट बंद है तो port या nil बारे में जानकारी लौटाता है

जानकारी (बंदरगाह, कल्पना)

यदि पोर्ट बंद है तो port या nil बारे में जानकारी लौटाता है

list()

वर्तमान नोड में सभी बंदरगाहों की सूची लौटाता है

monitor(port)

कॉलिंग प्रक्रिया से दिए गए port निगरानी शुरू करता है

खुला (नाम, विकल्प)

एक बंदरगाह का name जो एक टपल name और options की एक सूची है

प्रकार

नाम ()

name() ::
  {:spawn, charlist() | binary()}
  | {:spawn_driver, charlist() | binary()}
  | {:spawn_executable, charlist() | atom()}
  | {:fd, non_neg_integer(), non_neg_integer()}

कार्य

करीब (बंदरगाह)

close(port()) :: true

port बंद कर देता port

अधिक जानकारी के लिए, देखें :erlang.port_close/1

संकलक द्वारा झुका हुआ।

कमांड (पोर्ट, डेटा, विकल्प \\ [])

command(port(), iodata(), [:force | :nosuspend]) :: boolean()

पोर्ट ड्राइवर port लिए data भेजता है।

अधिक जानकारी के लिए, देखें :erlang.port_command/2

संकलक द्वारा झुका हुआ।

कनेक्ट (पोर्ट, पीआईडी)

connect(port(), pid()) :: true

port पहचानकर्ता को एक pid साथ pid

अधिक जानकारी के लिए, देखें :erlang.port_connect/2

संकलक द्वारा झुका हुआ।

डेमनीटर (मॉनिटर_ क्रोम, विकल्प \\ []) (1.6.0 के बाद से)

demonitor(reference(), options :: [:flush | :info]) :: boolean()

मॉनिटर दिए गए reference द्वारा पहचाने गए मॉनिटर।

अगर monitor_ref एक संदर्भ है जिसे कॉलिंग प्रक्रिया monitor(port) कॉल करके प्राप्त होती है, तो वह मॉनिटरिंग बंद हो जाती है। यदि निगरानी पहले से ही बंद है, तो कुछ भी नहीं होता है।

अधिक जानकारी के लिए देखें :erlang.demonitor/2

संकलक द्वारा झुका हुआ।

जानकारी (बंदरगाह)

यदि पोर्ट बंद है तो port या nil बारे में जानकारी लौटाता है।

अधिक जानकारी के लिए, देखें :erlang.port_info/1

जानकारी (बंदरगाह, कल्पना)

info(port(), atom()) :: {atom(), term()} | nil

यदि पोर्ट बंद है तो port या nil बारे में जानकारी लौटाता है।

अधिक जानकारी के लिए, देखें :erlang.port_info/2

सूची()

list() :: [port()]

वर्तमान नोड में सभी बंदरगाहों की सूची लौटाता है।

संकलक द्वारा झुका हुआ।

मॉनिटर (पोर्ट) (1.6.0 के बाद से)

monitor(port() | {name :: atom(), node :: atom()} | name() :: atom()) ::
  reference()

कॉलिंग प्रक्रिया से दिए गए port निगरानी शुरू करता है।

मॉनिटर पोर्ट प्रक्रिया के मर जाने के बाद, एक संदेश को मॉनिटरिंग प्रक्रिया में दिया जाता है:

{:DOWN, ref, :port, object, reason}

कहा पे:

  • ref इस फ़ंक्शन द्वारा दिया गया एक मॉनिटर संदर्भ है;
  • object या तो port निगरानी की जा रही है (जब पोर्ट आईडी द्वारा निगरानी की जा रही है) या {name, node} (जब पोर्ट नाम से निगरानी की जा रही है);
  • reason बाहर निकलने का कारण है।

अधिक जानकारी के लिए देखें :erlang.monitor/2

संकलक द्वारा झुका हुआ।

खुला (नाम, विकल्प)

open(name(), list()) :: port()

एक बंदरगाह का name जो एक टपल name और options की एक सूची है।

ऊपर दिए गए मॉड्यूल प्रलेखन में दस्तावेजीकरण और समर्थित name मानों के उदाहरण हैं, जिनका सारांश नीचे दिया गया है:

  • {:spawn, command} - एक बाहरी प्रोग्राम चलाता है। command में प्रोग्राम का नाम होना चाहिए और वैकल्पिक रूप से अंतरिक्ष द्वारा अलग किए गए तर्कों की एक सूची होनी चाहिए। यदि उनके नाम में स्थान के साथ कार्यक्रम या तर्क पारित करते हैं, तो अगले विकल्प का उपयोग करें।
  • {:spawn_executable, filename} - निरपेक्ष फ़ाइल नाम फ़ाइल नाम द्वारा दी गई निष्पादन योग्य चलाता है। तर्क :args विकल्प के माध्यम से पारित किया जा सकता है।
  • {:spawn_driver, command} - तथाकथित पोर्ट ड्राइवर को पैदा करता है।
  • {:fd, fd_in, fd_out} - VM द्वारा खोले गए फ़ाइल डिस्क्रिप्टर, fd_in और fd_out तक पहुँचता है।

अधिक जानकारी और विकल्पों की सूची के लिए, देखें :erlang.open_port/2

संकलक द्वारा झुका हुआ।