باستخدام coroutines الأصلي في جاوة

تدعم العديد من اللغات الحديثة العمل مع coroutines على مستوى اللغة. لا تدعم Java حاليًا coroutines ، ولكن هناك أمل في أن تتغير الأشياء في المستقبل.

في C ++ 20 ، من المخطط تقديم دعم للعمل مع coroutines.
باستخدام JNI يمكننا كتابة coroutines في C ++ واستخدامها في تعليمات Java البرمجية.

دعنا نفكر في ما يمكن أن يكتب الكوريتين الأصليين وكيفية استخدامه في كود جافا.

يتيح لك المولد إنشاء سلسلة من القيم من نوع معين ، في حين يتم إنشاء القيم بتكاسل ومتزامن.

/* C++ code */ generator<int> generate(int count) { for (int i = 0; i < count; i++) { co_yield i; } } 

  /* Java code */ Generator<Integer> gen1 = Coroutine.yield(5); Generator<Float> gen2 = Coroutine.yield(1f, 5); Generator<Double> gen3 = Coroutine.yield(v -> v * 2, 1d, 5); for (int item : gen1) { System.out.println("yield value: " + item); } 

مولد غير متزامن يسمح لك بإنشاء سلسلة من القيم من نوع معين ، في حين يتم إنشاء القيم كسول وغير متزامن.

  /* C++ code */ async_generator<int> generate(int count) { for (int i = 0; i < count; i++) { co_await 1s; co_yield i; } } 

  /* Java code */ Generator<Integer> gen1 = Coroutine.yieldAsync(5); Generator<Float> gen2 = Coroutine.yieldAsync(1f, 5); Generator<Double> gen3 = Coroutine.yieldAsync(v -> v * 2, 1d, 5); for (int item : gen1) { System.out.println("yield value: " + item); } 

تقوم المهمة بحساب غير متزامن ، والذي يتم تنفيذه بتكاسل ، بينما لا يتم تنفيذ coroutine حتى تبدأ المهمة بشكل صريح.

Coroutines يمكن أن تستخدم كما يتدفق الضوء. في هذه الحالة ، يمكن أن يكون عدد سلاسل العمليات قيد التشغيل في النظام محدودًا ، على سبيل المثال ، لا يزيد عن 1000. ويمكن تشغيل coroutine بقدر ما تريد.

عند بدء تشغيل coroutine ، يتم التحقق مما إذا كان جاهزًا. إذا لم يكن الأمر كذلك ، يتم إيقاف coroutine مؤقتًا ويقوم نظام التشغيل بتمرير المعالج إليه. في هذه المرحلة ، يتم تنفيذ جزء مفيد من التعليمات البرمجية. عندما يكون coroutine جاهزًا ، يتم تنفيذ تجديد coroutine.

  /* C++ code */ struct awaiter { bool await_ready() const { return false; } void await_resume() {} void await_suspend(std::coroutine_handle<> handler) { /* invoke java/jni code */ if (!handler.done()) { handler.resume(); } } }; co_await awaiter{}; 

كما هو الحال عند بدء موضوع ، يمكنك تمرير Runnable أو Callable إلى coroutine.

  /* Java code */ Coroutine.await(() -> { int sum = 5 + 10; }); Task<Integer> task = Coroutine.await(() -> { int sum = 5 + 10; return sum; }); 

المؤقت مؤقتاً المهمة الحالية للمدة المطلوبة.

  auto operator co_await(const std::chrono::system_clock::duration& duration) { return timer{duration}; } co_await 10ms; 

يمكن استخدامها كبديل لـ Thread.sleep ().

  Coroutine.await(10, TimeUnit.MILLISECONDS); 

يمكن أيضًا استخدام Coroutines لكتابة رمز غير محظور للعمل مع نظام الملفات والشبكة وما إلى ذلك.

كما ترون ، فإن coroutines تجعل كتابة التعليمات البرمجية غير المتزامنة أسهل ، مما يسمح بتنفيذ أجزاء من التعليمات البرمجية دون حظر الدفق.

ستظهر الخطوط الأساسية التي يخططون للبدء بها في C ++ 20 كميزات لغة خالصة.
من المخطط إضافة المولدات والمهام و coroutines الأخرى إلى معيار C ++ 23 أو إصدار أحدث.
يمكنك كتابة coroutines الخاصة بك بنفسك أو استخدام مكتبة جاهزة ، على سبيل المثال cppcoro .

تدعم شركات Compilers MVSC ، Clang بالفعل coroutines كملحق ، ودول مجلس التعاون الخليجي في مرحلة التطوير فقط.

يمكن الاطلاع على شفرة المصدر الكاملة على github: code

Source: https://habr.com/ru/post/ar474394/


All Articles