هل يمكن لأي شخص أن يشرح بنية Pid في Erlang؟

StackOverflow https://stackoverflow.com/questions/243363

  •  04-07-2019
  •  | 
  •  

سؤال

هل يمكن لأي شخص أن يشرح بنية Pid في Erlang؟

يبدو Pids مثل هذا: <A.B.C> ، على سبيل المثال.<0.30.0>، لكني أود أن أعرف ما معنى هذه "البتات" الثلاثة:أ، ب، ج.

يبدو أن القيمة "A" تكون دائمًا 0 على العقدة المحلية، ولكن هذه القيمة تتغير عندما يكون مالك معرف التعريف موجودًا على عقدة أخرى.

هل من الممكن إرسال رسالة مباشرة إلى عقدة بعيدة باستخدام معرف التعريف (Pid) فقط؟شئ مثل هذا :<4568.30.0>!رسالة، دون الحاجة إلى تحديد اسم العملية المسجلة واسم العقدة بشكل صريح ({proc_name, Node}!رسالة ) ؟

هل كانت مفيدة؟

المحلول

تتكون معرفات العملية المطبوعة <ABC> من 6:

  • A ، رقم العقدة (0 هو العقدة المحلية ، رقم تعسفي لعقدة عن بعد)
  • ب، أول 15 بت من رقم العملية (فهرس في جدول العملية) 7
  • C، البتات 16-18 من رقم العملية (نفس رقم العملية مثل B) 7

داخليًا، يبلغ عرض رقم العملية 28 بت في محاكي 32 بت.يأتي التعريف الغريب لـ B وC من R9B والإصدارات السابقة من Erlang حيث كان B عبارة عن معرف عملية 15 بت وكان C عبارة عن عداد التفاف يتم زيادته عند الوصول إلى الحد الأقصى لمعرف العملية وإعادة استخدام المعرفات الأقل.

في توزيع إرلانج، تكون معرفات PID أكبر قليلاً لأنها تتضمن ذرة العقدة بالإضافة إلى المعلومات الأخرى.(تنسيق PID الموزع)

عندما يتم إرسال معرف PID داخلي من عقدة إلى أخرى، يتم تحويله تلقائيًا إلى نموذج PID خارجي/موزع، لذا ما قد يكون <0.10.0> (inet_db) على عقدة واحدة قد ينتهي الأمر بـ <2265.10.0> عند إرسالها إلى عقدة أخرى.يمكنك فقط الإرسال إلى معرفات PID هذه كالمعتاد.

% get the PID of the user server on OtherNode
RemoteUser = rpc:call(OtherNode, erlang,whereis,[user]), 

true = is_pid(RemoteUser),

% send message to remote PID
RemoteUser ! ignore_this, 

% print "Hello from <nodename>\n" on the remote node's console.
io:format(RemoteUser, "Hello from ~p~n", [node()]). 

لمزيد من المعلومات، راجع: هيكل PID الداخلي, معلومات إنشاء العقدة, التفاعل المضاد لإنشاء العقدة مع EPMD

نصائح أخرى

إذا أتذكر هذا صحيح والشكل هو <nodeid,serial,creation>. 0 هو العقدة الحالية مثل الكثير من الكمبيوتر لديه دائما اسم المضيف "مضيف" للإشارة إلى نفسه. هذا هو إلى الذاكرة القديمة حتى أنه قد لا تكون صحيحة 100٪ صعبة.

ولكن نعم. هل يمكن بناء معرف المنتج مع list_to_pid/1 على سبيل المثال.

PidString = "<0.39.0>",
list_to_pid(PidString) ! message.

وبطبيعة الحال. كنت تستخدم فقط أيا كانت الطريقة التي تحتاج إلى استخدام لبناء PidString الخاص بك. ربما كتابة دالة الذي يولد عليها واستخدامها بدلا من PidString مثل هذه:

list_to_pid( make_pid_from_term({proc_name, Node}) ) ! message

معرف العملية <ABC> يتكون من:

  • A، معرف العقدة ليس عشوائيًا ولكنه الفهرس الداخلي لتلك العقدة في dist_entry.(إنه في الواقع العدد الصحيح لفتحة الذرة لاسم العقدة.)
  • B، فهرس العملية الذي يشير إلى الفهرس الداخلي في proctab، (0 -> MAXPROCS).
  • C، المسلسل الذي يزيد في كل مرة يتم الوصول إلى MAXPROCS.

لا يتم عرض علامة الإنشاء المكونة من 2 بت في معرف المنتج ولكن يتم استخدامها داخليًا وتزداد في كل مرة تتم فيها إعادة تشغيل العقدة.

ووPID يشير إلى عملية وطاولة العقدة. بحيث يمكنك فقط إرسال رسالة مباشرة إلى PID إذا هو معروف في العقدة التي لديك المكالمة.

ومن الممكن أن يكون هذا العمل إذا كانت العقدة لديك دعوة من سبق يعرف حول العقدة التي عملية قيد التشغيل.

وبصرف النظر عن ما قاله الآخرون، قد تجد هذه تجربة بسيطة مفيدة لفهم ما يجري داخليا:

1> node().
nonode@nohost
2> term_to_binary(node()).
<<131,100,0,13,110,111,110,111,100,101,64,110,111,104,111,
  115,116>>
3> self().                
<0.32.0>
4> term_to_binary(self()).
<<131,103,100,0,13,110,111,110,111,100,101,64,110,111,104,
  111,115,116,0,0,0,32,0,0,0,0,0>>

وهكذا، يمكنك حد ذاتها أن اسم عقدة يتم تخزين داخليا في معرف المنتج. مزيد من المعلومات في هذا القسم of تعلم أن بعض إرلانج.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top