সিরিয়াল কিউতে প্রেরণ_কেন্দ্রিক এবং প্রেরন_সিন্যাসের মধ্যে পার্থক্য?


125

আমি এই জাতীয় সিরিয়াল সারি তৈরি করেছি:

    dispatch_queue_t _serialQueue = dispatch_queue_create("com.example.name", DISPATCH_QUEUE_SERIAL);

এর মধ্যে পার্থক্য কি dispatch_asyncবলা হয়

 dispatch_async(_serialQueue, ^{ /* TASK 1 */ });
 dispatch_async(_serialQueue, ^{ /* TASK 2 */ });

এবং dispatch_syncএই সিরিয়াল কাতারে এভাবে ডাকা হয়?

 dispatch_sync(_serialQueue, ^{ /* TASK 1 */ });
 dispatch_sync(_serialQueue, ^{ /* TASK 2 */ });

আমার বোঝাটি হ'ল, কোন প্রেরণের পদ্ধতিটি নির্বিশেষে TASK 1কার্যকর করা হবে এবং কার্যকর করা হবে আগে TASK 2, সঠিক?

উত্তর:


409

হ্যাঁ. সিরিয়াল সারি ব্যবহার করে ক্রিয়াকলাপের ক্রমিক কার্য সম্পাদন নিশ্চিত করে। পার্থক্যটি হ'ল dispatch_syncকেবলমাত্র ব্লকটি শেষ dispatch_asyncহওয়ার পরে ফিরে আসে যখন এটি সারিটিতে যুক্ত হওয়ার পরেও ফিরে আসে এবং শেষ নাও হতে পারে।

এই কোডের জন্য

dispatch_async(_serialQueue, ^{ printf("1"); });
printf("2");
dispatch_async(_serialQueue, ^{ printf("3"); });
printf("4");

এটা তোলে প্রিন্ট পারে 2413বা 2143বা 1234কিন্তু 1সবসময় সামনে3

এই কোডের জন্য

dispatch_sync(_serialQueue, ^{ printf("1"); });
printf("2");
dispatch_sync(_serialQueue, ^{ printf("3"); });
printf("4");

এটি সর্বদা মুদ্রণ 1234


দ্রষ্টব্য: প্রথম কোডের জন্য, এটি মুদ্রণ করবে না1324 । কারণ printf("3")হল প্রেষিত পর printf("2") মৃত্যুদন্ড কার্যকর করা হয়। এবং কোনও কাজ প্রেরণের পরে কেবল কার্যকর করা যেতে পারে ।


কার্য সম্পাদনের সময় কোনও পরিবর্তন করে না। এই কোডটি সর্বদা মুদ্রণ করে12

dispatch_async(_serialQueue, ^{ sleep(1000);printf("1"); });
dispatch_async(_serialQueue, ^{ printf("2"); });

যা হতে পারে তা হ'ল

  • থ্রেড 1: সিরিয়াল কাতারে সময় সাশ্রয়ী টাস্ক (টাস্ক 1) প্রেরণ_কেন্দ্রিক করুন
  • থ্রেড 2: টাস্ক 1 চালানো শুরু করুন
  • থ্রেড 1: সিরিয়াল কাতারে আরেকটি কাজ (টাস্ক 2) প্রেরণ করুন_পরিচালনা করুন
  • থ্রেড 2: টাস্ক 1 সমাপ্ত। কার্য সম্পাদন 2 শুরু করুন
  • থ্রেড 2: টাস্ক 2 সমাপ্ত।

এবং আপনি সবসময় দেখতে পাবেন 12


7
এটি 2134 এবং 1243
মাত্তিও গোব্বি

আমার প্রশ্ন হ'ল আমরা কেন এটি স্বাভাবিক পদ্ধতির মতো করিনি? printf("1");printf("2") ;printf("3") ;printf("4")- এর সাথে তুলনা করুনdispatch_sync
androniennn

দ্বিতীয় উদাহরণের জন্য @androniennn? কারণ dispatch_sync(_serialQueue, ^{ /*change shared data*/ });একই সাথে কিছু অন্যান্য থ্রেড চলতে পারে ।
ব্রায়ান চেন

1
@ asma22 একাধিক থ্রেড / প্রেরণের সারির মধ্যে একটি নন-থ্রেড নিরাপদ বস্তুটি ভাগ করে নেওয়া খুব দরকারী। আপনি যদি কেবল সিরিয়াল কাতারে এই জিনিসটি অ্যাক্সেস করেন তবে আপনি জানেন যে আপনি এটি নিরাপদে অ্যাক্সেস করছেন।
ব্রায়ান চেন

1
আমি সিরিয়াল এক্সিকিউশন মানে না । দৃষ্টিকোণে যে সমস্ত কাজ একই ক্রিয়াকলাপের অন্যান্য কার্যগুলিতে ক্রমিক সম্পর্কিত সম্পাদিত হয়। কারণ এখনও এটি অন্যান্য কাতারে একই সাথে হতে পারে। এটি জিসিডির পুরো পয়েন্ট যা কাজগুলি প্রেরণ এবং একযোগে সম্পাদন করা যেতে পারে।
ব্রায়ান চেন

19

dispatch_syncএবং মধ্যে পার্থক্য dispatch_asyncসহজ।

আপনার দুটি উদাহরণে TASK 1সর্বদা কার্যকর করা হবে TASK 2কারণ এটি আগে প্রেরণ করা হয়েছিল।

ইন dispatch_syncউদাহরণস্বরূপ, যাইহোক, আপনি প্রাণবধ করা হবে না TASK 2হওয়া পর্যন্ত TASK 1পাঠানো হয়েছে এবং মৃত্যুদন্ড কার্যকর । একে বলা হয় "ব্লকিং" । আপনার কোডটি কার্য সম্পাদন না করা পর্যন্ত (বা "ব্লক") অপেক্ষা করে।

ইন dispatch_asyncউদাহরণস্বরূপ, আপনার কোড সম্পন্ন সঞ্চালনের জন্য অপেক্ষা করা হবে না। উভয় ব্লকই সারিতে প্রেরণ করবে (এবং প্রেরিত হবে) এবং আপনার বাকী কোডগুলি সেই থ্রেডে চালানো চালিয়ে যাবে। তারপরে ভবিষ্যতের কোনও পর্যায়ে (আপনার কিউতে আরও কী প্রেরণ করা হয়েছে তার উপর নির্ভর করে) Task 1কার্যকর করা হবে এবং তারপরে Task 2কার্যকর করা হবে।


2
আমি মনে করি আপনার ভুল অর্ডার পেতে। প্রথম উদাহরণটি হ'ল asyncনন-ব্লক করা সংস্করণ
ব্রায়ান চেন

আপনার উত্তরটি আমি কী বোঝাতে চাইছি তার সম্পাদনা করেছি । যদি এটি না হয় তবে দয়া করে এটিকে পরিবর্তন করুন এবং স্পষ্ট করে দিন।
জেআরজি-বিকাশকারী

1
যদি আপনি একই কিউতে dispatch_sync এবং তারপরে dispatch_async কল করেন? (এবং বিপরীতে)
0xSina

1
সিরিয়াল কাতারে, উভয় কাজ একের পর এক সম্পাদিত হয়। প্রথম ক্ষেত্রে, কলার প্রথম ব্লকটি শেষ হওয়ার জন্য অপেক্ষা করে তবে দ্বিতীয় ব্লকের জন্য অপেক্ষা করে না। দ্বিতীয় ক্ষেত্রে, কলার প্রথম ব্লকটি শেষ হওয়ার জন্য অপেক্ষা করে না, তবে দ্বিতীয় ব্লকের জন্য অপেক্ষা করে। কিন্তু যেহেতু কাতারি ক্রমগুলি ব্লকগুলি কার্যকর করে, কলার কার্যকরভাবে উভয়টি শেষ করার জন্য অপেক্ষা করে।
gnasher729

1
একটি ব্লক নিজস্ব কাতারে একটি প্রেরণ_অ্যাসিঙ্ক করতেও পারে (আরও ব্লকগুলি যুক্ত করা হবে যা পরে কার্যকর করা হবে); নিজস্ব সিরিয়াল কাতারে বা প্রধান সারিটিতে dispatch_sync অচল করে দেওয়া হবে। এই পরিস্থিতিতে, কলার মূল ব্লকটি শেষ হওয়ার অপেক্ষায় থাকবে, তবে অন্য ব্লকের জন্য নয়। কেবল মনে রাখবেন: dispatch_sync ব্লকের সারিটির শেষে রাখে, কাতার সেই ব্লকটি শেষ না হওয়া পর্যন্ত কোড চালায় এবং তারপরে dispatch_sync প্রদান করে। dispatch_async সারিটির শেষে ব্লকটি যুক্ত করে।
gnasher729

5

এটি সমস্ত মূল সারি সম্পর্কিত। এখানে 4 টি অনুমতি দেওয়া আছে।

i) সিরিয়াল সারি, প্রেরণ অ্যাসিঙ্ক: এখানে কাজগুলি একের পর এক কার্যকর করা হবে, তবে মূল থ্রেড (ইউআই-তে প্রভাব) প্রত্যাবর্তনের জন্য অপেক্ষা করবে না

ii) সিরিয়াল সারি, প্রেরণক্রমের সিঙ্ক: এখানে কার্যগুলি একের পর এক কার্যকর করা হবে, তবে মূল থ্রেড (ইউআই-তে প্রভাব) পিছিয়ে থাকবে

iii) একযোগে সারি, প্রেরণ অ্যাসিঙ্ক: এখানে কার্যগুলি সমান্তরালভাবে কার্যকর হবে এবং মূল থ্রেড (ইউআই-তে প্রভাব) প্রত্যাবর্তনের জন্য অপেক্ষা করবে না এবং মসৃণ হবে।

iv) একত্রে সারি, প্রেরণের সিঙ্ক: এখানে কার্যগুলি সমান্তরালভাবে কার্যকর হবে তবে মূল থ্রেড (ইউআই-তে প্রভাব) পিছিয়ে যাবে

আপনার পরবর্তী বা পরবর্তী কাজের জন্য কোনও পূর্ববর্তী কাজ থেকে আউটপুট প্রয়োজন কিনা তা নির্ভর করে আপনার যুগ্ম বা সিরিয়াল সারি পছন্দ choice আপনি যদি পূর্ববর্তী কাজটির উপর নির্ভর করেন তবে ক্রমিক কাতাকে অবলম্বন করুন অন্যথায় সমবর্তী সারিতে নিন।

এবং সর্বশেষে এটি মূল থ্রেডে ফিরে ratingোকার উপায় যখন আমরা আমাদের ব্যবসা শেষ করি:

DispatchQueue.main.async {
     // Do something here
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.