2016-10-27 17 views
10

ओएस क्लास के लिए, मुझे वर्तमान में लिनक्स कर्नेल में थ्रेड-सुरक्षित कतार बनाना है जो कि सिस्को का उपयोग करने के साथ इंटरैक्ट करता है।क्या कतार के एक महत्वपूर्ण खंड में आपसी बहिष्कार के लिए एक म्यूटेक्स के बजाय बाइनरी सेमफोर का उपयोग करने के कोई फायदे हैं?

अब महत्वपूर्ण वर्गों के लिए मेरी आंत महसूस करना है कि मैं mutex_lock और mutex_unlockmutex.h शीर्षलेख में फ़ंक्शंस का उपयोग करना चाहता हूं। हालांकि, मुझे बताया गया था कि मैं down_interruptible और up के साथ semaphore.h हेडर में बाइनरी सेमफोर का उपयोग कर सकता हूं, और यह बेहतर होगा।

मैंने Difference between binary semaphore and mutex के माध्यम से पढ़ा है: इससे, मैं समझता हूं कि म्यूटेक्स का मुख्य लाभ यह है कि यह स्वामित्व को कितना दृढ़ता से लागू करता है, और सेमफोर का लाभ यह है कि चूंकि यह स्वामित्व को लागू नहीं करता है, आप इसका उपयोग कर सकते हैं दो (एकाधिक?) विभिन्न धागे के बीच सिंक्रनाइज़ेशन तंत्र के रूप में।

मेरा प्रश्न यह है कि बाइनरी सेमफोर के फायदे क्या हैं, यदि आप इसे म्यूटेक्स के समान तरीके से उपयोग करते हैं। अधिक स्पष्ट रूप से अगर मैं लिखा है:

down() 
/* critical */ 
up() 

उसी तरह है कि मैं क्या करना होगा

mutex_lock() 
/* critical */ 
mutex_unlock() 

में वहाँ कुछ प्रदर्शन लाभ है क्योंकि यह एक म्युटेक्स की तुलना में कम सुरक्षित है है? क्या मैं कुछ भूल रहा हूँ?


यहाँ कोड है कि मैं यदि आप और अधिक संदर्भ चाहते धागा सुरक्षित बनाना चाहते का एक छोटा सा टुकड़ा है (यह मेरी पहली सी proj कभी न करें):

#define MESSAGE_MAX_SIZE 512 

typedef struct list_head list_node; 

/* Create message struct */ 
typedef struct { 
    size_t size; 
    list_node node; 
    char data[MESSAGE_MAX_SIZE]; 
} Message; 

/* Create the linked list queue with dummy head */ 
struct { 
    size_t size; 
    list_node head; 
} my_q = { 0, LIST_HEAD_INIT(my_q.head) }; 

/* 
    Adds a new item to the tail of the queue. 

    @data: pointer to data to add to list 
    @len: size of the data 
*/ 
asmlinkage long sys_enqueue(const void __user *data, long len) { 
    long res = 0; 
    Message *msg = 0; 

    if (len < 0) return EINVAL; 
    if (len > MESSAGE_MAX_SIZE) return E2BIG; 

    msg = kmalloc(sizeof(Message), GFP_KERNEL); 
    if (msg == 0) return ENOMEM; 

    res = copy_from_user(msg->data, data, len); 
    if (res != 0) return EFAULT; 

    /* Start Critical Section */ 

    my_q.size++; 
    list_add_tail(&msg->node, &my_q.head); 

    /* End Critical Section */ 

    return 0; 
} 
+0

क्या आपकी कतार को कभी भी रिकर्सिव लॉकिंग की आवश्यकता होगी या प्राथमिकता विचलन से निपटना होगा? –

+0

प्राथमिकता विचलन के लिए नहीं, और मुझे पूरा यकीन है कि मुझे रिकर्सिव लॉकिंग की आवश्यकता नहीं होगी। – m0meni

+2

फिर उस बिंदु पर, मुझे लगता है कि यह प्रदर्शन के लिए नीचे आता है। और जब यह प्रदर्शन होता है, तो सबसे अच्छी बात यह है कि दोनों प्रोफाइल करें और देखें कि क्या होता है। मेरा आंत महसूस होता है कि अगर वे लगभग समान प्रदर्शन करते हैं, तो मैं एक म्यूटेक्स के साथ रहूंगा, लेकिन दूसरों के पास निश्चित रूप से बेहतर जवाब हो सकते हैं। –

उत्तर

11

अनुभवजन्य साक्ष्य के अभाव में, मैं किताब लिनक्स कर्नेल विकास

यह (यानी म्युटेक्स) एक की गिनती के साथ एक सेमाफोर के लिए इसी तरह बर्ताव करता है से बोली चाहते हैं, लेकिन यह एक सरल इंटरफेस, अधिक कुशल प्रदर्शन, और इसके उपयोग पर अतिरिक्त बाधाएं।

इसके अतिरिक्त, कई बाधाएं हैं जो म्यूटेक्स पर लागू होती हैं लेकिन सेमफोर नहीं। म्यूटेक्स धारण करते समय प्रक्रिया जैसी चीजें बाहर नहीं निकल सकती हैं। इसके अलावा, यदि CONFIG_DEBUG_MUTEXES कर्नेल विकल्प सक्षम है, तो म्यूटेक्स पर लागू होने वाली सभी बाधाओं को डिबगिंग चेक द्वारा सुनिश्चित किया जाता है।

तो, जब तक म्यूटेक्स का उपयोग न करने का कोई अच्छा कारण न हो, तो यह पहली पसंद होनी चाहिए।

+3

मैं इसके साथ भी जाऊंगा। –

5

डिफ़ॉल्ट लॉकिंग आदिम स्पिनलॉक है। म्यूटेक्स केवल तभी समझ में आता है जब आपको लॉक रखने के दौरान सोना पड़ता है, जो आप निश्चित रूप से उपर्युक्त कोड नमूना में नहीं करते हैं।

#define MESSAGE_MAX_SIZE 512 

typedef struct list_head list_node; 

क्यों?

/* Create message struct */ 
typedef struct { 
    size_t size; 
    list_node node; 
    char data[MESSAGE_MAX_SIZE]; 
} Message; 

अजीब आदेश, नोड पॉइंटर या तो पहले या आखिरी होना चाहिए।

/* Create the linked list queue with dummy head */ 
struct { 
    size_t size; 
    list_node head; 
} my_q = { 0, LIST_HEAD_INIT(my_q.head) }; 

/* 
    Adds a new item to the tail of the queue. 

    @data: pointer to data to add to list 
    @len: size of the data 
*/ 
asmlinkage long sys_enqueue(const void __user *data, long len) { 

घुंघराले ब्रैकेट अगली पंक्ति पर होना चाहिए। हस्ताक्षरित प्रकार की लंबाई क्यों है?

long res = 0; 
    Message *msg = 0; 

आप इन्हें क्यों शुरू कर रहे हैं और आप न्यूल के विरोध में सूचक को 0 क्यों सेट कर रहे हैं?

if (len < 0) return EINVAL; 

वापसी विवरण अगली पंक्ति पर होना चाहिए। यह भी ध्यान दें कि इस स्थिति को प्रासंगिक नहीं किया जाएगा यदि प्रकार के साथ शुरू करने के लिए हस्ताक्षर किए गए थे।

if (len > MESSAGE_MAX_SIZE) return E2BIG; 

    msg = kmalloc(sizeof(Message), GFP_KERNEL); 

क्यों sizeof नहीं (* संदेश)

if (msg == 0) return ENOMEM; 

    res = copy_from_user(msg->data, data, len); 
    if (res != 0) return EFAULT; 

इस संदेश लीक।

/* Start Critical Section */ 

    my_q.size++; 
    list_add_tail(&msg->node, &my_q.head); 

    /* End Critical Section */ 

    return 0; 
} 
+1

यह "व्यक्तिगत राय" नहीं है लेकिन मौजूदा लिनक्स कर्नेल कोडिंग दिशानिर्देशों के अनुरूप है, जिसका आप किसी स्पष्ट कारण के लिए उल्लंघन नहीं कर रहे हैं। आपके वास्तविक प्रश्न के संबंध में आपको क्या करना चाहिए पहले 2 वाक्यों में समझाया गया था। अपने दृष्टिकोण के साथ शुभकामनाएँ। –

+1

मुझे खेद है अगर मैं बर्खास्तगी के रूप में आया था। व्यक्तिगत राय से मेरा मतलब शैली था, क्योंकि यह सिर्फ मेरी अपनी परियोजना है कि मैं कर्नेल में योगदान नहीं दे रहा हूं, मुझे नहीं लगता था कि यह महत्वपूर्ण था। List_head के लिए -> list_node typedef यह इसलिए है क्योंकि list_head मुझे इतना अनजान नाम था। हस्ताक्षरित चर जैसे सामानों के लिए, वे हस्ताक्षर हैं जिन्हें मैं काम करने के लिए सौंपा गया था इसलिए मैंने उन्हें रखा। मेमोरी रिसाव के लिए, मैं एक डेक्यू फ़ंक्शन में kfree() को कॉल करता हूं जिसे मैंने यहां पोस्ट नहीं किया है। मैं 0 से अधिक पसंद करता हूं क्योंकि वे एक ही चीज़ हैं। एक प्रश्न: संदेश संरचना में नोड पहले क्यों होना चाहिए? – m0meni

+0

मैंने अपना डाउनवोट भी हटा दिया है। मुझे लगता है कि मैं अनचाहे कोड समीक्षा से नाराज था, और कामना की थी कि आपने पहले पंक्तियों पर अधिक विस्तार किया था जैसे कि जब वास्तव में केवल स्पिनलॉक की बजाय सोना आवश्यक होता है। – m0meni

संबंधित मुद्दे

 संबंधित मुद्दे