في إرلانج ، هل هناك أي طريقة يمكن لمرسل الرسائل الانتظار على الرد؟
سؤال
في إرلانج ، هل هناك أي طريقة يمكن لمرسل الرسائل الانتظار على الرد ، لذلك يستمر التنفيذ فقط بمجرد معالجة الرسالة؟
وأعني شيئًا كهذا:
Actor ! DoSomething
Continue to this next line of code when DoSomething has been processed
أعلم أنه يمكن إجراء رد اتصال عن طريق إرسال PID من المرسل ، ولكن هل هناك أي طريقة أخرى للانتظار؟
المحلول
أول شيء يجب فهمه هو أن إرلانج تم تصميمه للتعامل مع مرور الرسائل غير المتزامنة. على هذا النحو ، فإن الطريقة الوحيدة لتمرير رسالة متزامنة هي تنفيذ شيء يشبه الإقرار.
تخيل عمليتين ، P1 و P2. قد يقوم P1 بتشغيل الكود التالي:
%% process P1 takes the Pid of P2 as a parameter
%% and a Message to pass on to P2
p1(P2, Message) ->
P2 ! {self(), Message},
receive
{P2, ok}
after 5000 -> % this section is optional, times out after 5s
exit("P2 didn't process this!") % this kills P1
end.
P2 ، على جانبها قد تدير ما يلي فقط:
p2() ->
receive
{From, Message} ->
io:format("P2 received message ~p~n",[Message]),
%% processing is done!
From ! {self(), ok}
end.
إذن ، قد تفرخ P2 كعملية جديدة. هذا واحد سوف يجلس في انتظار أي رسالة. عندما تقوم بالاتصال P1 ، فإنه يرسل رسالة إلى P2 ، والتي تقوم بعد ذلك بمعالجتها (io:format/2
) والرد على P1. نظرًا لأن P1 كان ينتظر الرد ، لم يتم تشغيل رمز إضافي داخل هذه العملية.
هذه هي الطريقة الأساسية والوحيدة لتنفيذ مكالمات حظر. الاقتراحات للاستخدام gen_server:call
تنفذ تقريبًا ما أظهرته للتو. إنه مخفي عن المبرمج.
نصائح أخرى
يمكنك استخدام أ تسلم منع:
http://www.erlang.org/doc/reference_manual/expressions.html#id2270724
القراءة من المستند:
تلقي أبدا لا يفشل. يتم تعليق التنفيذ ، وربما إلى أجل غير مسمى ، حتى تصل الرسالة التي تتطابق مع أحد الأنماط مع تسلسل حارس حقيقي.
بمعنى آخر ، أرسل رسالة وانتظر الرد.
إذا كانت عملية الاستلام أ gen_server, ، يمكنك استخدام gen_server:call
. على سبيل المثال:
gen_server:call(Pid, Message),
% At this point, we know that the other process has answered.
لا ، لا يوجد سوى رسالة غير متزامنة.
إذا كنت تريد أن تكون فلسفيًا بعض الشيء ، فمن الصعب للغاية تحديد موعد معالجة الرسالة تلقائيًا. هل هي عندما وصلت الرسالة إلى العملية ، تم استلامها ولكن لم يتم التصرف عليها بعد أو في وقت ما عندما يتم التصرف عليها من خلال عملية الاستلام. إنه يشبه الحصول على إشعار تلقائي عندما "يقرأ" بريدي. نعم ، لقد رأوا ذلك لكنهم قرأوها حقًا؟
يعتمد فقط على المواقف jldupont. إذا قام متصفح الويب بتقديم طلب إلى WebMachine للحصول على مورد Erlang طويل المدى ، فلا توجد طريقة لاستخدام فريق عمل لتلبية هذا الطلب.