تدعم العديد من اللغات الحديثة العمل مع coroutines على مستوى اللغة. لا تدعم Java حاليًا coroutines ، ولكن هناك أمل في أن تتغير الأشياء في المستقبل.
في C ++ 20 ، من المخطط تقديم دعم للعمل مع coroutines.
باستخدام JNI يمكننا كتابة coroutines في C ++ واستخدامها في تعليمات Java البرمجية.
دعنا نفكر في ما يمكن أن يكتب الكوريتين الأصليين وكيفية استخدامه في كود جافا.
يتيح لك
المولد إنشاء سلسلة من القيم من نوع معين ، في حين يتم إنشاء القيم بتكاسل ومتزامن.
generator<int> generate(int count) { for (int i = 0; i < count; i++) { co_yield i; } }
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); }
مولد غير متزامن يسمح لك بإنشاء سلسلة من القيم من نوع معين ، في حين يتم إنشاء القيم كسول وغير متزامن.
async_generator<int> generate(int count) { for (int i = 0; i < count; i++) { co_await 1s; co_yield i; } }
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.
struct awaiter { bool await_ready() const { return false; } void await_resume() {} void await_suspend(std::coroutine_handle<> handler) { if (!handler.done()) { handler.resume(); } } }; co_await awaiter{};
كما هو الحال عند بدء موضوع ، يمكنك تمرير Runnable أو Callable إلى coroutine.
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