মুটেক্স উদাহরণ / টিউটোরিয়াল? [বন্ধ]


177

আমি মাল্টিথ্রেডিংয়ে নতুন, এবং কীভাবে মুটিেক্স কাজ করে তা বোঝার চেষ্টা করছিলাম। প্রচুর গুগলিং করেছে এবং আমি একটি শালীন টিউটোরিয়াল খুঁজে পেয়েছি তবে এটি কীভাবে কাজ করে তা নিয়ে এখনও কিছু সন্দেহ থেকে যায় কারণ আমি নিজের প্রোগ্রাম তৈরি করেছি যেখানে লকিংয়ের কাজ হয়নি।

মিউটেক্সের একটি একেবারে অ-স্বজ্ঞাত সিন্ট্যাক্স pthread_mutex_lock( &mutex1 );, যেখানে মনে হচ্ছে মিউটেক্সটি লক করা হচ্ছে, যখন আমি সত্যিই লক করতে চাই তা অন্য কিছু পরিবর্তনশীল। এই সিনট্যাক্সটির অর্থ কি মুটেক্সকে লক করা কোডের একটি অঞ্চল লক করে মুটেেক্স আনলক না করা অবধি? তাহলে থ্রেডগুলি কীভাবে জানতে পারে যে অঞ্চলটি লক করা আছে? [ আপডেট: থ্রেডগুলি জানে যে মেমরি বেড়া দিয়ে অঞ্চলটি লক হয়েছে ]। এবং এই জাতীয় ঘটনাটিকে কি সমালোচনামূলক বিভাগ বলা হবে না? [ আপডেট: সমালোচনামূলক বিভাগের অবজেক্টগুলি কেবল উইন্ডোজে পাওয়া যায়, যেখানে বস্তুগুলি মুটেক্সেসের চেয়ে দ্রুত এবং এটি কেবলমাত্র থ্রেডে দৃশ্যমান হয় যা এটি কার্যকর করে। অন্যথায়, সমালোচনা বিভাগটি কেবলমাত্র একটি মুটেক্স দ্বারা সুরক্ষিত কোডের ক্ষেত্রকে বোঝায় ]

সংক্ষেপে, আপনি দয়া করে সবচেয়ে সহজ সম্ভাব্য মুটেক্স উদাহরণ প্রোগ্রাম এবং এটি কীভাবে কাজ করে তার যুক্তিতে সহজতম সম্ভাব্য ব্যাখ্যা দিয়ে সহায়তা করতে পারেন? আমি নিশ্চিত এটি অন্যান্য নবাগতদের প্রচুর সাহায্য করবে ।


2
একটি সাধারণ টিউটোরিয়াল (এটি থ্রেড, টিবিবি বা pthreads উত্থাপন) এর প্রয়োজনীয়তার উপর জোর দেওয়া অব্যাহত রাখুন: বিভ্রান্তির উদাহরণ: 1. স্ট্যাকওভারফ্লো / প্রশ্ন / 3528877/… ২. স্ট্যাকওভারফ্লো / প্রশ্নগুলি / 2979525/… 3। stackoverflow.com/questions/2095977/to-mutex-or-not-to-mutex 4. স্ট্যাকওভারফ্লো / প্রশ্ন / 3931026/… 5. স্ট্যাকওভারফ্লো / প্রশ্ন
নভে

1
আমি এটি আপত্তিজনকভাবে বোঝাতে চাই না, তবে আপনার শেষ মন্তব্যটি আমার কাছে যা পরামর্শ দেয় তা হ'ল আমাদের তুলনায় কম উপমা এবং একটি মুটেেক্স কীভাবে কাজ করে এবং আমাদের সেগুলি কেন দরকার তার আরও ভাল প্রযুক্তিগত ব্যাখ্যা প্রয়োজন।
সান জ্যাকিন্তো

@ সান: কোনও অপরাধ নেওয়া হয়নি :) আমার মন্তব্যগুলি কেবলমাত্র এমন একটি পরামর্শ দেওয়ার জন্য হয়েছিল যে কোনও নবজাতক মুটেক্সের সংক্ষিপ্ততম এবং পরিষ্কার ব্যাখ্যা পেতে পারে। অনেকগুলি উপমা নবজাতকের জন্য বিভ্রান্তি পেতে পারে, তাই আলাদা আলাদা উপমা আলাদাভাবে রাখা উচিত। আমার কাছে ক্যোয়ারী এবং উত্তরগুলি পোস্ট করার পুরো কারণটি হ'ল নবাগত হিসাবে, দীর্ঘ ব্যাখ্যা এবং কোডের নমুনাগুলির মাধ্যমে পড়তে আমার খুব কষ্ট হয়েছে found আমি চাই না যে অন্য কেউ যন্ত্রণার মধ্য দিয়ে যায়।
নাভ

2
@ কোরি: যদি এই উত্তরটি উন্নত করা যায় তবে আমি আপনার পরামর্শগুলি গ্রহণ করে খুশি হব। আমি কেবল খুশি যে অন্যান্য অনেক লোক এটি সহায়ক বলে মনে করেছে। যদি এটি আপনাকে সহায়তা না করে তবে অন্যান্য ব্যক্তিদের থেকেও উত্তর রয়েছে যারা অন্যান্য মুটেক্স টিউটোরিয়ালগুলিকে নির্দেশ করেছেন। এত নেতিবাচক হবে কেন?
নাভ

উত্তর:


278

বিশ্বজুড়ে নতুনদের কাছে ধারণাটি ব্যাখ্যা করার জন্য আমার নম্র প্রচেষ্টাটি এখানে চলে গেছে: ( আমার ব্লগেও রঙিন কোডেড সংস্করণ )

প্রচুর লোক তাদের প্রিয়জনের সাথে কথা বলার জন্য একাকী ফোন বুথে (তাদের কাছে মোবাইল ফোন নেই) ছুটে যায়। বুথের ডোর-হ্যান্ডেলটি পাওয়া প্রথম ব্যক্তি, যিনি ফোনটি ব্যবহারের অনুমতি পেয়েছেন। যতক্ষণ না তিনি ফোনটি ব্যবহার করেন ততক্ষণ তাকে দরজার হ্যান্ডেল ধরে রাখতে হবে, অন্যথায় অন্য কেউ হ্যান্ডেলটি ধরে ফেলবে, তাকে বাইরে ফেলে দেবে এবং স্ত্রীর সাথে কথা বলবে :) এর মতো কোনও সারি ব্যবস্থা নেই। যখন ব্যক্তি তার কল শেষ করে, বুথ থেকে বেরিয়ে দরজার হ্যান্ডেলটি ছেড়ে যায়, দরজার হ্যান্ডেলটি ধরার জন্য পরবর্তী ব্যক্তিকে ফোনটি ব্যবহার করার অনুমতি দেওয়া হবে।

একটি থ্রেড হয়: প্রতিটি ব্যক্তি mutex হল: দরজার হাতল লক হল: ব্যক্তির হাত রিসোর্স হল: ফোন


যে কোনও থ্রেডে কিছু লাইন কোডের সম্পাদন করতে হবে যা একই সাথে অন্যান্য থ্রেডের মাধ্যমে একই সাথে সংশোধন করা উচিত নয় (তার স্ত্রীর সাথে কথা বলার জন্য ফোনটি ব্যবহার করে) প্রথমে একটি মুটেক্সের উপর একটি লক অর্জন করতে হবে (বুথের দরজার হাতলটি আটকে থাকা) )। তবেই কোনও থ্রেড সেই লাইন কোডগুলি (ফোন কল করা) চালাতে সক্ষম হবে।

থ্রেডটি সেই কোডটি কার্যকর করার পরে, এটি মুটেক্সে লকটি প্রকাশ করা উচিত যাতে অন্য থ্রেডটি মুটেক্সে একটি লক অর্জন করতে পারে (অন্যান্য ব্যক্তিরা ফোন বুথ অ্যাক্সেস করতে সক্ষম হচ্ছেন)।

[ রিয়েল-ওয়ার্ল্ড এক্সক্লুসিভ অ্যাক্সেস বিবেচনা করার সময় মিউটেক্স থাকার ধারণাটি কিছুটা অযৌক্তিক, তবে প্রোগ্রামিং বিশ্বে আমার ধারণা অন্যান্য থ্রেডকে 'দেখতে' দেওয়ার কোনও উপায় নেই যে কোনও থ্রেড ইতিমধ্যে কিছু লাইন কোডের সম্পাদন করছে। পুনরাবৃত্তিকারী মুটেক্সেস ইত্যাদির ধারণা রয়েছে তবে এই উদাহরণটি কেবল আপনাকে প্রাথমিক ধারণাটি দেখানোর জন্যই হয়েছিল। আশা করি উদাহরণটি আপনাকে ধারণার একটি পরিষ্কার চিত্র দেয় gives ]

সি ++ 11 থ্রেডিং সহ:

#include <iostream>
#include <thread>
#include <mutex>

std::mutex m;//you can use std::lock_guard if you want to be exception safe
int i = 0;

void makeACallFromPhoneBooth() 
{
    m.lock();//man gets a hold of the phone booth door and locks it. The other men wait outside
      //man happily talks to his wife from now....
      std::cout << i << " Hello Wife" << std::endl;
      i++;//no other thread can access variable i until m.unlock() is called
      //...until now, with no interruption from other men
    m.unlock();//man lets go of the door handle and unlocks the door
}

int main() 
{
    //This is the main crowd of people uninterested in making a phone call

    //man1 leaves the crowd to go to the phone booth
    std::thread man1(makeACallFromPhoneBooth);
    //Although man2 appears to start second, there's a good chance he might
    //reach the phone booth before man1
    std::thread man2(makeACallFromPhoneBooth);
    //And hey, man3 also joined the race to the booth
    std::thread man3(makeACallFromPhoneBooth);

    man1.join();//man1 finished his phone call and joins the crowd
    man2.join();//man2 finished his phone call and joins the crowd
    man3.join();//man3 finished his phone call and joins the crowd
    return 0;
}

সংকলন এবং ব্যবহার চালানো g++ -std=c++0x -pthread -o thread thread.cpp;./thread

সুস্পষ্টভাবে ব্যবহার করার পরিবর্তে lockএবং unlock, আপনি এখানে যেমন দেখানো হয়েছে তেমন বন্ধনী ব্যবহার করতে পারেন , যদি আপনি এটির সুবিধার জন্য কোনও স্কোপড লক ব্যবহার করেন । স্কোপড লকগুলির উপরে একটি হালকা কর্মক্ষমতা রয়েছে।


2
@ সান: আমি সৎ হব; হ্যাঁ আমি এটিকে পছন্দ করি যে আপনি সম্পূর্ণ নবাগতকে বিশদ (প্রবাহ সহ) ব্যাখ্যা করার জন্য যথাসাধ্য চেষ্টা করেছেন। কিন্তু, (দয়া করে আমাকে ভুল বুঝবেন না) এই পোষ্টের উদ্দেশ্যটি ছিল ধারণাটি একটি সংক্ষিপ্ত ব্যাখ্যায় রাখা (অন্যান্য উত্তরগুলি দীর্ঘ টিউটোরিয়ালের দিকে নির্দেশিত)। আমি আশা করি আপনার পুরো উত্তরটি অনুলিপি করে আলাদা উত্তর হিসাবে পোস্ট করার জন্য অনুরোধ করলে আপনি আপত্তি করবেন না? যাতে আমি আপনার উত্তরটি নির্দেশ করতে আমার উত্তরটি রোলব্যাক করতে এবং সম্পাদনা করতে পারি।
নাভ

2
@ টম সেক্ষেত্রে আপনার সেই মিটেক্সটি অ্যাক্সেস করা উচিত নয়। এটির অপারেশনগুলি এনক্যাপসুলেটেড হওয়া উচিত যাতে এটি যা রক্ষা করছে তা এই জাতীয় টমফুলারি থেকে সুরক্ষিত থাকবে। আপনি যখন লাইব্রেরির উন্মুক্ত এপিআই ব্যবহার করেন তখন গ্রন্থাগারটি থ্রেড-নিরাপদ হওয়ার গ্যারান্টিযুক্ত থাকে, তবে আপনি নিজের ভাগ করা আইটেমগুলি সুরক্ষিত করার জন্য আলাদা আলাদা মিউটেক্স অন্তর্ভুক্ত করতে নিরাপদ। অন্যথায়, আপনি প্রস্তাবিত হিসাবে আপনি সত্যিই একটি নতুন দরজা হ্যান্ডেল যুক্ত করা হয়।
সান জ্যাকিন্টো

2
আমার বক্তব্য প্রসারিত করার জন্য, আপনি যা করতে চান তা হ'ল বুথের চারপাশে আরও একটি বৃহত্তর ঘর যুক্ত করা। ঘরে শৌচাগার ও ঝরনাও থাকতে পারে। ধরা যাক যে ঘরে ঘরে একবারে মাত্র 1 জন ব্যক্তিকে অনুমতি দেওয়া হয়। আপনার অবশ্যই রুমটি ডিজাইন করতে হবে যাতে এই ঘরে একটি হ্যান্ডেল সহ একটি দরজা থাকা উচিত যা ফোন বুথের মতো ঘরে প্রবেশ রক্ষা করে। সুতরাং এখন আপনার কাছে অতিরিক্ত মিটেক্স থাকলেও আপনি যে কোনও প্রকল্পে ফোন বুথটি পুনরায় ব্যবহার করতে পারেন। আরেকটি বিকল্প হ'ল রুমের প্রতিটি ডিভাইসের জন্য লকিংয়ের ব্যবস্থা উন্মুক্ত করা এবং রুম বর্গের লকগুলি পরিচালনা করা। যে কোনও উপায়ে, আপনি একই জিনিসটিতে নতুন লক যুক্ত করবেন না।
সান জ্যাকিন্টো

8
আপনার সি ++ 11 থ্রেডিংয়ের উদাহরণটি ভুল । টিবিবিও তাই, ক্লু নামটি স্কোপড লক
জোনাথন ওয়াকলি

3
আমি জনাথন উভয় সম্পর্কেই ভালভাবে অবগত। আপনি আমার লেখা বাক্যটি মিস করেছেন বলে মনে হয়েছিল (could've shown scoped locking by not using acquire and release - which also is exception safe -, but this is clearer। স্কোপড লকিং ব্যবহার করার ক্ষেত্রে, তারা কী ধরণের অ্যাপ্লিকেশন তৈরি করছে তার উপর নির্ভর করে এটি বিকাশকারীদের অবধি। এই উত্তরটির অর্থ মিটেক্স ধারণার প্রাথমিক বোঝাপড়া এবং এটির সমস্ত জটিলতায় না পড়ার উদ্দেশ্যে বোঝানো হয়েছিল, সুতরাং আপনার মন্তব্য এবং লিঙ্কগুলি স্বাগত তবে এই টিউটোরিয়ালটির সুযোগের বাইরে কিছুটা নয়।
নাভ

41

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

//somewhere long ago, we have i declared as int
void my_concurrently_called_function()
{
  i++;
}

এই ফাংশনটির ইন্টার্নালগুলি এত সহজ দেখাচ্ছে। এটি কেবল একটি বিবৃতি। তবে, একটি সাধারণ সিউডো-এসেম্বলি ভাষার সমতুল্য হতে পারে:

load i from memory into a register
add 1 to i
store i back into memory

যেহেতু সমতুল্য সমাবেশ-ভাষার নির্দেশাবলী সমস্তই i তে বর্ধিত ক্রিয়াকলাপ সম্পাদনের জন্য প্রয়োজনীয়, আমরা বলি যে আমি বৃদ্ধি করাই একটি নন-অ্যাটমিক অপারেশন। একটি পারমাণবিক অপারেশন হ'ল একটি নির্দেশিকা কার্যকর করা শুরু হওয়ার পরে বাধা না পাওয়ার নিশ্চয়তা সহ হার্ডওয়্যারটিতে সম্পূর্ণ করা যায়। আমি বৃদ্ধি 3 টি পরমাণু নির্দেশাবলীর একটি চেইন নিয়ে গঠিত। সমকালীন সিস্টেমে যেখানে বেশ কয়েকটি থ্রেড ফাংশনটিকে ডেকে দেখায়, কোনও থ্রেড ভুল সময়ে পড়ে বা লিখলে সমস্যা দেখা দেয়। কল্পনা করুন আমাদের একসাথে দুটি থ্রেড চলছে এবং একজন অন্যের সাথে সাথেই ফাংশনটি কল করে। আসুন আমরা এটাও বলে রাখি যে আমরা 0 থেকে শুরু করে এসেছি। এছাড়াও ধরে নিও যে আমাদের প্রচুর রেজিস্টার রয়েছে এবং দুটি থ্রেড সম্পূর্ণ আলাদা রেজিস্টার ব্যবহার করছে, সুতরাং কোনও সংঘর্ষ হবে না। এই ইভেন্টগুলির আসল সময় হতে পারে:

thread 1 load 0 into register from memory corresponding to i //register is currently 0
thread 1 add 1 to a register //register is now 1, but not memory is 0
thread 2 load 0 into register from memory corresponding to i
thread 2 add 1 to a register //register is now 1, but not memory is 0
thread 1 write register to memory //memory is now 1
thread 2 write register to memory //memory is now 1

যা ঘটেছে তা হল আমরা একই সাথে দুটি থ্রেড বাড়িয়েছি, আমাদের ফাংশনটি দু'বার কল হয়ে যায়, তবে ফলাফলটি সেই সত্যের সাথে অসামঞ্জস্যপূর্ণ। দেখে মনে হচ্ছে ফাংশনটি কেবল একবার ডাকা হয়েছিল। এটি কারণ মেশিন পর্যায়ে পারমাণবিকতা "ভাঙ্গা", যার অর্থ থ্রেডগুলি একে অপরকে বাধা দিতে পারে বা ভুল সময়ে এক সাথে কাজ করতে পারে।

এটি সমাধান করার জন্য আমাদের একটি প্রক্রিয়া দরকার। আমাদের উপরের নির্দেশাবলীতে কিছু ক্রম চাপিয়ে দেওয়া দরকার। একটি সাধারণ প্রক্রিয়া হ'ল একটি বাদে সমস্ত থ্রেড ব্লক করা। প্যাথ্রেড মিউটেক্স এই প্রক্রিয়াটি ব্যবহার করে।

যে কোনও থ্রেডে কোডের কয়েকটি লাইন কার্যকর করতে হবে যা একই সময়ে অন্যান্য থ্রেডের দ্বারা অনিরাপদভাবে ভাগ করা মানগুলিকে সংশোধন করতে পারে (তার স্ত্রীর সাথে কথা বলার জন্য ফোনটি ব্যবহার করে), প্রথমে একটি মিউটেক্সে একটি লক অর্জন করা উচিত। এইভাবে, যে কোনও থ্রেডে ভাগ করা ডেটা অ্যাক্সেসের প্রয়োজন তা অবশ্যই মুটেক্স লকটির মধ্য দিয়ে যেতে হবে। তবেই কোনও থ্রেড কোডটি কার্যকর করতে সক্ষম হবে। কোডের এই বিভাগটিকে একটি সমালোচনা বিভাগ বলা হয়।

থ্রেডটি সমালোচনামূলক বিভাগটি সম্পাদন করার পরে, এটি মুটেক্সে লকটি প্রকাশ করা উচিত যাতে অন্য থ্রেডটি মিউটেক্সে একটি লক অর্জন করতে পারে।

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

প্রযুক্তিগতভাবে বলতে গেলে, একটি মিটেক্স কীভাবে কাজ করে? আমরা আগে বর্ণিত একই জাতি শর্তে ভোগে না? Pthread_mutex_lock () একটি ভেরিয়েবলের একটি সহজ বৃদ্ধি যে আরও কিছুটা জটিল নয়?

প্রযুক্তিগতভাবে বলতে গেলে, আমাদের সাহায্য করার জন্য আমাদের কিছু হার্ডওয়্যার সহায়তা প্রয়োজন। হার্ডওয়্যার ডিজাইনাররা আমাদের মেশিনের নির্দেশনা দেয় যা একাধিক কাজ করে তবে পরমাণু হওয়ার নিশ্চয়তা থাকে are এই জাতীয় নির্দেশের একটি সর্বোত্তম উদাহরণ হ'ল টেস্ট অ্যান্ড সেট (টিএএস)। কোনও উত্সটিতে একটি লক অর্জন করার চেষ্টা করার সময়, আমরা টিএএস ব্যবহার করতে পারি মেমরির কোনও মান 0 আছে কিনা তা পরীক্ষা করে দেখতে পারেন If এটি যদি হয় তবে আমাদের সংকেতটি হবে যে উত্সটি ব্যবহার হচ্ছে এবং আমরা কিছুই করি না (বা আরও সঠিকভাবে) , আমরা কিছু ব্যবস্থার দ্বারা অপেক্ষা করি A একটি pthreads mutex আমাদের অপারেটিং সিস্টেমের একটি বিশেষ কাতারে রাখবে এবং যখন সংস্থানটি উপলব্ধ হবে তখন আমাদের জানাবে D ডम्बर সিস্টেমগুলি আমাদের একটি কঠোর স্পিন লুপ করার প্রয়োজন হতে পারে, শর্তটি বারবার পরীক্ষা করে) । যদি মেমরির মান 0 না হয় তবে টিএএস অন্য নির্দেশাবলী ব্যবহার না করে 0 থেকে অন্য কিছুতে অবস্থান সেট করে। এটা ' আমাদের পারমাণবিকতা দেওয়ার জন্য দুটি সমাবেশ নির্দেশকে 1 এর সাথে সংযুক্ত করার মতো s সুতরাং, পরীক্ষার এবং মানটি পরিবর্তন করা (যদি পরিবর্তন যথাযথ হয়) একবার শুরু হয়ে গেলে বাধা দেওয়া যায় না। আমরা এই জাতীয় নির্দেশের উপরে মিটেক্সেস তৈরি করতে পারি।

দ্রষ্টব্য: কিছু বিভাগ পূর্ববর্তী উত্তরের অনুরূপ উপস্থিত হতে পারে। আমি সম্পাদনা করার জন্য তার আমন্ত্রণটি গ্রহণ করেছি, সে এটির মূল পদ্ধতিটিকেই পছন্দ করেছিল, তাই আমি যা ছিল তা রাখছি যা তার সামান্য কিছুটা কথা বলে age


1
সান, আপনাকে অনেক ধন্যবাদ। আমি আপনার উত্তরের সাথে লিঙ্ক করেছি :) আসলে, আমার উদ্দেশ্য ছিল যে আপনি আমার উত্তরটি + আপনার উত্তরটি নিয়ে যান এবং প্রবাহ বজায় রাখতে এটি একটি পৃথক উত্তর হিসাবে পোস্ট করেন post আপনি যদি আমার উত্তরের কোনও অংশ পুনরায় ব্যবহার করেন তবে আমার সত্যিই আপত্তি নেই। আমরা যাই হোক না কেন নিজের জন্য এটি করছি না।
নাভি

13

আমার জানা সেরা থ্রেড টিউটোরিয়ালটি এখানে:

https://computing.llnl.gov/tutorials/pthreads/

আমি পছন্দ করি এটি কোনও নির্দিষ্ট প্রয়োগের পরিবর্তে এপিআই সম্পর্কে লেখা হয়েছিল এবং এটি আপনাকে সিঙ্ক্রোনাইজেশন বুঝতে সহায়তা করার জন্য কয়েকটি দুর্দান্ত সাধারণ উদাহরণ দেয়।


আমি সম্মতি দিয়েছি এটি অবশ্যই একটি ভাল টিউটোরিয়াল, তবে এটি একটি একক পৃষ্ঠায় প্রচুর তথ্য এবং প্রোগ্রামগুলি দীর্ঘ। আমি পোস্ট করা প্রশ্নটি হ'ল "আমার একটি স্বপ্ন আছে" বক্তৃতার মিউটেক্স সংস্করণ, যেখানে নবাবিরা মুটেক্সগুলি সম্পর্কে শেখার সহজ উপায় খুঁজে পাবেন এবং কীভাবে অজ্ঞাত জ্ঞানীয় সিনট্যাক্স কাজ করে তা বুঝতে পারবেন (এটি একটি ব্যাখ্যা যা সমস্ত টিউটোরিয়ালে অনুপস্থিত) ।
নভে

7

আমি সম্প্রতি এই পোস্টে হোঁচট খেয়েছি এবং মনে করি এটি স্ট্যান্ডার্ড লাইব্রেরির সি ++ ১১ টি মুটেক্স (যথা স্টাডি :: মিটেক্স) এর একটি আপডেট সমাধান দরকার।

আমি নীচে কিছু কোড আটকিয়েছি (একটি মুটেক্সের সাথে আমার প্রথম পদক্ষেপ - আমি হ্যান্ডেল, সেটএভেন্ট, ওয়েটফর্ম মাল্টিপলঅবজেক্টস ইত্যাদির সাথে উইন 32 এ একত্রে চুক্তি শিখলাম)।

যেহেতু এটি আমার প্রথম প্রয়াস :: মুটেক্স এবং বন্ধুদের সাথে, তাই আমি মন্তব্য, পরামর্শ এবং উন্নতি দেখতে পছন্দ করব!

#include <condition_variable>
#include <mutex>
#include <algorithm>
#include <thread>
#include <queue>
#include <chrono>
#include <iostream>


int _tmain(int argc, _TCHAR* argv[])
{   
    // these vars are shared among the following threads
    std::queue<unsigned int>    nNumbers;

    std::mutex                  mtxQueue;
    std::condition_variable     cvQueue;
    bool                        m_bQueueLocked = false;

    std::mutex                  mtxQuit;
    std::condition_variable     cvQuit;
    bool                        m_bQuit = false;


    std::thread thrQuit(
        [&]()
        {
            using namespace std;            

            this_thread::sleep_for(chrono::seconds(5));

            // set event by setting the bool variable to true
            // then notifying via the condition variable
            m_bQuit = true;
            cvQuit.notify_all();
        }
    );


    std::thread thrProducer(
        [&]()
        {
            using namespace std;

            int nNum = 13;
            unique_lock<mutex> lock( mtxQuit );

            while ( ! m_bQuit )
            {
                while( cvQuit.wait_for( lock, chrono::milliseconds(75) ) == cv_status::timeout )
                {
                    nNum = nNum + 13 / 2;

                    unique_lock<mutex> qLock(mtxQueue);
                    cout << "Produced: " << nNum << "\n";
                    nNumbers.push( nNum );
                }
            }
        }   
    );

    std::thread thrConsumer(
        [&]()
        {
            using namespace std;
            unique_lock<mutex> lock(mtxQuit);

            while( cvQuit.wait_for(lock, chrono::milliseconds(150)) == cv_status::timeout )
            {
                unique_lock<mutex> qLock(mtxQueue);
                if( nNumbers.size() > 0 )
                {
                    cout << "Consumed: " << nNumbers.front() << "\n";
                    nNumbers.pop();
                }               
            }
        }
    );

    thrQuit.join();
    thrProducer.join();
    thrConsumer.join();

    return 0;
}

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

4

ফাংশনটি pthread_mutex_lock()হয় কলিং থ্রেডের জন্য মিউটেক্স অর্জন করে বা মুদ্রাটি অর্জন করা না হওয়া পর্যন্ত থ্রেডটি ব্লক করে। সম্পর্কিত pthread_mutex_unlock()মুটেক্স প্রকাশ করে।

ম্যুটেক্সকে একটি সারি হিসাবে মনে করুন; প্রতিটি থ্রেড যা মুটেক্সটি অর্জন করার চেষ্টা করে তা সারির শেষ প্রান্তে স্থাপন করা হবে। যখন কোনও থ্রেড মিটেক্স প্রকাশ করে, কাতারের পরবর্তী থ্রেডটি বন্ধ হয়ে যায় এবং এখন চলছে।

একটি সমালোচনা বিভাগ কোডের একটি অঞ্চলকে বোঝায় যেখানে অ-নির্ধারণবাদ সম্ভব। প্রায়শই এটি কারণ একাধিক থ্রেড একটি ভাগ করা ভেরিয়েবল অ্যাক্সেস করার চেষ্টা করছে। এক ধরণের সিঙ্ক্রোনাইজেশন না হওয়া পর্যন্ত সমালোচনা বিভাগটি নিরাপদ নয়। একটি মিটেক্স লক সিঙ্ক্রোনাইজেশনের একটি রূপ।


1
এটি কি নিশ্চিত যে পরবর্তী প্রয়াসের থ্রেডটি প্রবেশ করবে?
আর্সেন এমকিটচায়ান

1
@ আরসেন কোনও গ্যারান্টি নেই এটি কেবল একটি সহায়ক উপমা।
খ্রিস্টিয়াকক

3

মিউটেক্স দ্বারা সুরক্ষিত অঞ্চলটি ব্যবহার করার আগে আপনি মুটেক্স ভেরিয়েবলটি পরীক্ষা করে দেখুন। সুতরাং আপনার pthread_mutex_lock () (বাস্তবায়নের উপর নির্ভর করে) mutex1 প্রকাশিত হওয়া অবধি অপেক্ষা করতে পারে বা এমন কোনও মান প্রত্যাবর্তন করে যা অন্য কেউ ইতিমধ্যে লক করে থাকলে লকটি পাওয়া যায় না।

Mutex সত্যিই কেবল একটি সরলীকৃত semaphore। আপনি যদি সেগুলি সম্পর্কে পড়েন এবং সেগুলি বুঝতে পারেন তবে আপনি মিটেক্সগুলি বুঝতে পারেন। এসওতে মিটেক্সেস এবং সেমফোরগুলি সম্পর্কিত বেশ কয়েকটি প্রশ্ন রয়েছে। বাইনারি সেমফোর এবং মিটেক্সের মধ্যে পার্থক্য , কখন আমাদের মুটেক্স ব্যবহার করা উচিত এবং কখন সেম্যাফোর ব্যবহার করা উচিত । প্রথম লিঙ্কে টয়লেটের উদাহরণটি যতটা ভাল উদাহরণ হিসাবে চিন্তা করা যায় is সমস্ত কোডটি কীটি উপলব্ধ রয়েছে কিনা তা পরীক্ষা করে দেখা হয় এবং তা যদি থাকে তবে তা সংরক্ষণ করে। লক্ষ্য করুন যে আপনি সত্যিই টয়লেট নিজেই সংরক্ষণ করেন না, তবে কী।


1
pthread_mutex_lockঅন্য কেউ লক ধরে রাখলে ফিরে আসতে পারে না। এটি এই ক্ষেত্রে অবরুদ্ধ এবং এটি পুরো বিষয়টি। pthread_mutex_trylockলকটি রাখা থাকলে ফাংশনটি ফিরে আসবে।
আর .. গীটহাব বন্ধ করুন ICE

1
হ্যাঁ, এটি বাস্তবায়ন কী তা আমি প্রথমে বুঝতে পারি নি।
মাকিস

3

শর্টেক্স মুটেক্স উদাহরণ সন্ধানকারীদের জন্য:

#include <mutex>
using namespace std;

int main() {
    mutex m;

    m.lock();
    // do thread-safe stuff
    m.unlock();

    return 0;
}

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