فشل في الحصول على مثيلات منفصلة لفئة ضمن mod_python
-
03-07-2019 - |
سؤال
أحاول تشغيل بعض أكواد python ضمن Apache 2.2 / mod_python 3.2.8.في النهاية، يقوم الكود بتنفيذ os.fork() وينتج عمليتين منفصلتين طويلتي المدى.يتعين على كل واحدة من هذه العمليات إنشاء مثيل منفصل للفئة لتجنب أي تصادم محتمل في التدفق الموازي.
class Foo(object):
pass
kidprocs = []
for kid in ('kid1', 'kid2'):
pid = os.fork()
if pid:
# parent
kidprocs.append(pid)
time.sleep(5)
else:
# child
fooobj = Foo()
print "Starting %s in sub-process %s" % (kid, os.getpid())
print "Kid fooobj: %s" % repr(fooobj)
os._exit(0)
for kidproc in kidprocs:
os.waitpid(kidproc, 0)
تبدو مخرجات الطباعة هذه كما يلي:
Starting kid1 in sub-process 20906
foo obj: <__main__.Foo instance at 0xb7da5fec>
Starting kid2 in sub-process 20909
foo obj: <__main__.Foo instance at 0xb7da5fec>
كما ترون، حصلت على نفس الكائن لكلتا العمليتين الفرعيتين.هل لديك فكرة عن سبب حدوث ذلك ضمن mod_python وهل هناك طريقة للحصول على مثيلات منفصلة على أي حال؟شكرًا جزيلاً.
المحلول
موقع الذاكرة الذي قدمه repr()
الوظيفة هي عنوان في الذاكرة الظاهرية، وليست عنوانًا في الذاكرة العامة للنظام.كل عملية من عملياتك التي يتم إرجاعها بواسطة fork() لها مساحة ذاكرة افتراضية خاصة بها والتي تختلف تمامًا عن العمليات الأخرى.إنهم لا يتشاركون الذاكرة.
يحرر: تعليقات بير بريان أدناه، من الناحية الفنية، فإنها تشارك الذاكرة حتى تقرر النواة فصلها (عندما يكتب الطفل إلى جزء من الذاكرة المشتركة).ومع ذلك، فإن السلوك هو نفسه فعليًا.
بنية برامجك هي نفسها، لذا تستخدم لغة بايثون نفس موقع الذاكرة الافتراضية في مخزن الذاكرة الظاهرية المميز لكل عملية لكل من الأشياء المتطابقة الخاصة بك لكل طفل.
إذا قمت بالفعل بتعديل محتوى الكائنات واختبارها، فسترى أنه على الرغم من أن موقع الذاكرة يبدو متماثلًا، إلا أنهما كائنان مختلفان تمامًا، لأنهما ينتميان إلى عمليتين مختلفتين.في الواقع، لا يمكنك تعديل أحدهما عن الآخر (بدون نوع من الاتصال بين العمليات للتوسط).