কীভাবে @ সিঙ্ক্রোনাইজড লক / আনলকটি অবজেক্টিভ-সি তে যায়?


201

@ সিংক্রোনাইজড পারস্পরিক বর্জনীয়তা অর্জনের জন্য "লক" এবং "আনলক" ব্যবহার করে না? কীভাবে এটি তখন লক / আনলক করে?

নিম্নলিখিত প্রোগ্রামটির আউটপুট কেবলমাত্র "হ্যালো ওয়ার্ল্ড"।

@interface MyLock: NSLock<NSLocking>
@end

@implementation MyLock

- (id)init {
    return [super init];
}

- (void)lock {
    NSLog(@"before lock");
    [super lock];
    NSLog(@"after lock");
}

- (void)unlock {
    NSLog(@"before unlock");
    [super unlock];
    NSLog(@"after unlock");
}

@end


int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    MyLock *lock = [[MyLock new] autorelease];
    @synchronized(lock) {
        NSLog(@"Hello World");
    }

    [pool drain];
}


10
আপনার যদি প্রয়োজন না হয় তবে আপনাকে আর ওভাররাইড করার দরকার নেই। রানটাইম স্বয়ংক্রিয়ভাবে সুপারক্লাসকে কল করে 'যদি আপনি কোনও পদ্ধতি ওভাররাইড না করেন।
কনস্টান্টিনো জারোহাস

3
একটি গুরুত্বপূর্ণ বিষয় লক্ষণীয় যে উপরের কোডটি সিঙ্ক্রোনাইজ করা হয়নি। lockবস্তুর প্রতি কলের উপর তৈরি করা হয়, তাই একটি মামলা হবে না যেখানে এক @synchronizedঅন্য খুঁজে ব্লক কেশ। এবং এর অর্থ কোনও পারস্পরিক বর্জন নেই)) অবশ্যই, উপরের উদাহরণটি অপারেশন করছে main, সুতরাং যাইহোক বাদ দেওয়ার মতো কিছুই নেই, তবে সেই কোডটি অন্য কোথাও অন্ধভাবে অনুলিপি করা উচিত নয়।
হট লিকস 26'15

3
এই এসও পৃষ্ঠাটি পড়ার পরে, আমি সিদ্ধান্ত নিয়েছি @ সিঙ্ক্রোনাইজডকে আরও কিছুটা ভাল করে তদন্ত করব এবং এটিতে একটি ব্লগ পোস্ট লিখব। আপনি এটি দরকারী খুঁজে পেতে পারেন: rykap.com/objective-c/2015/05/09/ সিংক্রোনাইজড
rjkaplan

উত্তর:


323

অবজেক্টিভ-সি ভাষার স্তরের সিঙ্ক্রোনাইজেশনটি মিটেক্স ব্যবহার করে, যেমনটি NSLockকরে। শব্দার্থগতভাবে কিছু ছোট প্রযুক্তিগত পার্থক্য রয়েছে, তবে এগুলিকে একটি সাধারণ (আরও আদিম) সত্তার উপরে প্রয়োগ করা দুটি পৃথক ইন্টারফেস হিসাবে মনে করা মূলত সঠিক is

বিশেষত NSLockএকটির সাথে @synchronizedআপনার একটি সুস্পষ্ট লক রয়েছে তবে আপনার সাথে একটি সংযোজিত লক রয়েছে যার সাথে আপনি সিঙ্ক্রোনাইজ করতে ব্যবহার করছেন with ভাষা স্তর লক করার সুবিধাটি সংকলক এটি বুঝতে পারে যাতে এটি স্কোপিংয়ের সমস্যাগুলি মোকাবেলা করতে পারে তবে যান্ত্রিকভাবে তারা মূলত একই আচরণ করে।

আপনি @synchronizedকম্পাইলার পুনর্লিখন হিসাবে ভাবতে পারেন :

- (NSString *)myString {
  @synchronized(self) {
    return [[myString retain] autorelease];
  }
}

রূপান্তরিত হয়:

- (NSString *)myString {
  NSString *retval = nil;
  pthread_mutex_t *self_mutex = LOOK_UP_MUTEX(self);
  pthread_mutex_lock(self_mutex);
  retval = [[myString retain] autorelease];
  pthread_mutex_unlock(self_mutex);
  return retval;
}

এটি ঠিক সঠিক নয় কারণ প্রকৃত রূপান্তরটি আরও জটিল এবং পুনরাবৃত্ত লকগুলি ব্যবহার করে তবে এটি পয়েন্টটি পাওয়া উচিত।


17
আপনি @ সিঙ্ক্রোনাইজড আপনার জন্য যে ব্যতিক্রম পরিচালনা করে তাও আপনি ভুলে যাচ্ছেন। এবং আমি এটি যেমন বুঝতে পারি, এর বেশিরভাগটি রানটাইম এ পরিচালনা করা হয়। এটি অযৌক্তিক লকস ইত্যাদির উপর অপ্টিমাইজেশনের অনুমতি দেয়
কুইন টেলর

7
যেমনটি আমি বলেছিলাম, প্রকৃত উত্পন্ন জিনিসগুলি আরও জটিল, তবে DWARF3 আনইন্ড টেবিলগুলি তৈরি করতে বিভাগের নির্দেশনাগুলি লেখার মতো আমার মনে হয়নি ;-)
লুই গারবার্গ

এবং আমি আপনাকে দোষ দিতে পারি না :-) এছাড়াও লক্ষ্য করুন যে ওএস এক্স DWARF এর পরিবর্তে Mach-O ফর্ম্যাটটি ব্যবহার করে।
কুইন টেলর

5
বাইনারি ফর্ম্যাট হিসাবে কেউ DWARF ব্যবহার করে না। ওএস এক্স ডিবাগ প্রতীকগুলির জন্য DWARF ব্যবহার করে এবং এটি শূন্য ব্যয়ে ব্যতিক্রমের জন্য DWARF
আনইন্ড

7
রেফারেন্সের জন্য, আমি ম্যাক ওএস এক্স ;-)
ব্যাকেন্ডগুলি লিখেছি

40

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

মূলত, @synchronized (...)এমন একটি সুবিধাজনক কাঠামো যা আপনার কোডকে প্রবাহিত করে। বেশিরভাগ সরল বিমূর্তনের মতো এটি ওভারহেডের সাথে যুক্ত হয়েছে (এটিকে একটি গোপন ব্যয় হিসাবে মনে করুন), এবং এটি সম্পর্কে সচেতন হওয়া ভাল, তবে যাইহোক এই জাতীয় নির্মাণগুলি ব্যবহার করার সময় কাঁচা অভিনয় সম্ভবত সর্বোচ্চ লক্ষ্য নয়।


1
সেই লিঙ্কটির মেয়াদ শেষ হয়ে গেছে। আপডেট হওয়া লিঙ্কটি এখানে: বিকাশকারী.অ্যাপল.
com

31

প্রকৃতপক্ষে

{
  @synchronized(self) {
    return [[myString retain] autorelease];
  }
}

সরাসরি রূপান্তরিত:

// needs #import <objc/objc-sync.h>
{
  objc_sync_enter(self)
    id retVal = [[myString retain] autorelease];
  objc_sync_exit(self);
  return retVal;
}

এই এআইপি আইওএস ২.০ থেকে উপলব্ধ এবং ব্যবহার করে আমদানি করা হয়েছে ...

#import <objc/objc-sync.h>

সুতরাং এটি পরিষ্কারভাবে ছোঁড়া ব্যতিক্রমগুলি পরিচালনা করার জন্য কোনও সমর্থন সরবরাহ করে না?
ডাস্টিন

এটি কোথাও নথিভুক্ত করা হয়?
jbat100

6
সেখানে ভারসাম্যহীন বন্ধনী রয়েছে।
পোটোসওয়টার

@ ডাস্টিন আসলে ডক্স থেকে এটি করে: "একটি সতর্কতামূলক ব্যবস্থা হিসাবে, @synchronizedব্লকটি সুরক্ষিত কোডটিতে স্পষ্টতই একটি ব্যতিক্রম হ্যান্ডলার যুক্ত করে This
পিটার

objc_sync_enter সম্ভবত pthread মিটেক্স ব্যবহার করবে, তাই লুই এর রূপান্তর আরও গভীর এবং সঠিক।
জ্যাক 21

3

অ্যাপল এর @ সিনক্রোনাইজড বাস্তবায়ন ওপেন সোর্স এবং এটি এখানে পাওয়া যাবে । মাইক অ্যাশ এই বিষয় সম্পর্কে দুটি সত্যিই আকর্ষণীয় পোস্ট লিখেছেন:

সংক্ষেপে এটিতে একটি টেবিল রয়েছে pthread_mutex_tযা লকগুলিতে অবজেক্ট পয়েন্টারগুলি (তাদের মেমরির ঠিকানাগুলি কী হিসাবে ব্যবহার করে) মানচিত্র করে , যা প্রয়োজনীয় হিসাবে তালাবদ্ধ এবং আনলক করা আছে।


-4

এটি কেবল প্রতিটি বস্তুর সাথে একটি সেমফোর সংযুক্ত করে এবং এটি ব্যবহার করে।


প্রযুক্তিগতভাবে, এটি একটি মিটেক্স লক তৈরি করে তবে প্রাথমিক ধারণাটি সঠিক। অ্যাপল ডিভাটি এখানে দেখুন: বিকাশকারী
মার্ক বেসি

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