سؤال

ما هو سلوك مؤشرات CX_ORACLE عند استخدام كائن الاتصال بواسطة مؤشرات ترابط مختلفة؟ كيف ستؤثر المولدات على هذا السلوك؟ على وجه التحديد...

تعديل: كانت وظيفة المثال الأصلي غير صحيحة ؛ تم إرجاع مولد من خلال وظيفة فرعية ، yield لم يتم استخدامه مباشرة في الحلقة. هذا يوضح متى finally يتم تنفيذها (بعد return هل) ، ولكن لا يزال لا يجيب على ما إذا كان يمكن استخدام المؤشر إذا بدأ مؤشر ترابط آخر في استخدام كائن الاتصال الذي تم إنشاء المؤشر منه. يبدو في الواقع (في بيثون 2.4 ، على الأقل) ، try...finally مع yield يسبب خطأ بناء الجملة.

def Get()
  conn = pool.get()
  try:
    cursor = conn.cursor()
    cursor.execute("select * from table ...")
    return IterRows(cursor)
  finally:
    pool.put(conn)

def IterRows(cursor):
  for r in cursor:
    yield r

Get() هي وظيفة تسمى مؤشرات ترابط متعددة. يتم إنشاء الاتصالات مع threaded=False جدال.

انا اتسائل...

  1. هو الموضوع 1 cursor الكائن لا يزال قابلاً للاستخدام إذا جاء الموضوع 2 ويستخدم نفس كائن الاتصال؟ إذا لم يكن كذلك ، ماذا قد يحدث؟

السلوك الذي أراه هو استثناء في CX_ORACLE يتحدث عن خطأ بروتوكول ، ثم يتبع segfault.

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

المحلول

يرى المستندات: threadsafety هو ، وأنا أقتبس ،

حاليا 2 ، مما يعني أن المواضيع قد تشارك الوحدة والاتصالات ، ولكن ليس المؤشرات.

لذا ، يبدو أن بنية "مجموعة المؤشرات" الخاصة بك (حيث يمكن استخدام مؤشر واحد من قبل مؤشرات ترابط مختلفة) خارج threadsafety مستوى. إنها ليست مشكلة في مشاركة الاتصالات (هذا جيد منذ مرورك threaded بشكل صحيح في مُنشئ الاتصال) ولكن المؤشرات. قد ترغب في تخزين كل مؤشر threading.local بعد المرة الأولى التي يستخدمها مؤشر ترابط ، بحيث يمكن أن يكون لكل مؤشر ترابط "تجمع" واحد (ليس تحسينًا رئيسيًا ، على الرغم من: صنع المؤشر الجديد ليس عملية شاقة).

wrt سؤالك 2 ، finally يتم تنفيذ البند عندما يكون كائن المولد (تم تصميمه بواسطة مكالمة إلى وظيفة المولد الخاصة بك Get) يتم كل ذلك - إما لأنه يرفع StopIteration, ، أو لأنه يجري جمع القمامة (عادةً لأن الإشارة الأخيرة إليها قد اختفت للتو). على سبيل المثال ، إذا كان المتصل هو:

def imthecaller():
  for i, row in enumerate(Get()):
    print i, row
    if i > 1: break
  # this is the moment the generators' finally-clause runs
  print 'bye'

ال finally ينفذ بعد (على الأكثر) 3 صفوف yieldإد.

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