18

यह एक साक्षात्कार प्रश्न है।क्या लिनक्स/यूनिक्स पर मल्टीप्रोसेसिंग मामले में म्यूटेक्स का उपयोग करना संभव है?

क्या लिनक्स/यूनिक्स पर मल्टीप्रोसेसिंग मामले में म्यूटेक्स का उपयोग करना संभव है?

मेरा विचार: नहीं, विभिन्न प्रक्रियाओं में अलग मेमोरी स्पेस है।

म्यूटेक्स का उपयोग केवल मल्टीथ्रेडिंग के लिए किया जाता है।

सेमफोर का उपयोग मल्टीप्रोसेसिंग के लिए सिंक्रनाइज़ेशन करने के लिए किया जाता है।

सही?

कोई भी टिप्पणी का स्वागत है।

धन्यवाद

+0

आप "बहु" से क्या मतलब है पर निर्भर करता है। यदि आप स्टैक ओवरफ्लो परिभाषा से जाते हैं, तो मल्टीप्रोसेसिंग में मल्टीथ्रेडिंग शामिल होगी। यदि आपका मतलब है "एकाधिक प्रक्रियाएं", तो आप सही हैं। –

+0

देखें http://stackoverflow.com/a/28479697/2189128 – Jeff

उत्तर

18
Mutual exclusion locks (mutexes) prevent multiple threads 
from simultaneously executing critical sections of code that 
access shared data (that is, mutexes are used to serialize 
the execution of threads). All mutexes must be global. A 
successful call for a mutex lock by way of mutex_lock() 
will cause another thread that is also trying to lock the 
same mutex to block until the owner thread unlocks it by way 
of mutex_unlock(). Threads within the same process or 
within other processes can share mutexes. 

Mutexes can synchronize threads within the **same process** or 
in ***other processes***. Mutexes can be used to synchronize 
threads between processes if the mutexes are allocated in 
writable memory and shared among the cooperating processes 
(see mmap(2)), and have been initialized for this task. 

प्रारंभ Mutexes या तो इंट्रा-प्रक्रिया या अंतर-प्रक्रिया, तर्क है कि म्युटेक्स की प्रारंभ करने के लिए परोक्ष या स्पष्ट रूप से पारित कर दिया पर आधार पर कर रहे हैं। एक स्थैतिक आवंटित म्यूटेक्स को स्पष्ट रूप से प्रारंभ करने की आवश्यकता नहीं है; डिफ़ॉल्ट रूप से, स्थैतिक रूप से आवंटित म्यूटेक्स को सभी शून्य के साथ प्रारंभ किया गया है और इसका दायरा कॉलिंग प्रक्रिया के भीतर होना निर्धारित है।

For inter-process synchronization, a mutex needs to be allo- 
cated in memory shared between these processes. Since the 
memory for such a mutex must be allocated dynamically, the 
mutex needs to be explicitly initialized using mutex_init(). 
+10

, इंटर-प्रोसेस सिंक्रनाइज़ेशन के लिए, साझा मेमोरी में आवंटित करने की आवश्यकता के अलावा, म्यूटेक्स को PTHREAD_PROCESS_SHARED विशेषता का भी उपयोग करना चाहिए, अन्यथा अपने निर्माता परिणामों की तुलना में किसी अन्य प्रक्रिया से म्यूटेक्स को अपरिभाषित व्यवहार में एक्सेस करना चाहिए (इसे देखें: http: // linux.die.net/man/3/pthread_mutexattr_setpshared): "प्रक्रिया-साझा विशेषता PTHREAD_PROCESS_SHARED पर सेट की गई है ताकि किसी मटेक्स को किसी भी थ्रेड द्वारा संचालित किया जा सके, जिसमें म्यूटेक्स आवंटित स्मृति तक पहुंच हो, भले ही म्यूटेक्स आवंटित हो स्मृति में आवंटित किया जाता है जिसे कई प्रक्रियाओं द्वारा साझा किया जाता है " – user1284631

5

काफी नहीं। POSIX धागे में process-shared attribute की अवधारणा है जिसका उपयोग म्यूटेक्स बनाने के लिए किया जा सकता है जिसे एकाधिक प्रक्रियाओं द्वारा संचालित किया जा सकता है।

आप साझा स्मृति में ऐसे म्यूटेक्स डाल सकते हैं ताकि कई प्रक्रियाएं इसमें मिल सकें।

चाहे LINUX इसे लागू करता है। मुझे यकीन नहीं है, मुझे इसे उपयोग करने की आवश्यकता नहीं थी क्योंकि यह अनावश्यक रूप से जटिल लगता है।

विशेषताओं के उपयोगी सटीक के लिए, मेरा उत्तर this question पर देखें।

0

हां, सामान्य रूप से लिनक्स में हमारे पास केवल अनामित म्यूटेक्स हैं जिसके कारण वे प्रक्रियाओं के बीच काम नहीं कर सकते हैं। इसे पाने के लिए हमें एक सेमफोर चाहिए।

विंडोज़ में, उनके नामित म्यूटेक्स की अवधारणा है जो हमें प्रक्रियाओं में म्यूटेक्स का उपयोग करने देती है।

+4

http://linux.die.net/man/3/pthread_mutexattr_init देखें - LINUX प्रक्रिया-साझा म्यूटेक्स के लिए अनुमति देता है। चाहे वे नामित हों या नहीं प्रासंगिक हैं, लिनक्स और यूनिक्स सामान्य साझा मेमोरी ब्लॉक को जोड़कर उन्हें बिना नाम के साझा कर सकते हैं। – paxdiablo

+0

हां, यह सही है। आप साझा ब्लॉक को संलग्न करके उनका उपयोग कर सकते हैं। :) –

+4

सटीक उत्तर नहीं। –

7

process-shared mutex का उपयोग करना काफी संभव है।

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

मुझे 2004 में Red Hat Linux का उपयोग करना याद है और उस समय यह दोनों प्रक्रियाओं को म्यूटेक्स और हालत चर साझा करता था।

2

मैं एक नामित म्युटेक्स लिए देख रहा था, ताकि मैं एक प्रक्रिया (गुण के कुछ सेट प्रति यकीन है कि केवल एक ही प्रक्रिया चल बनाने) की जीवन भर के लिए पारस्परिक अपवर्जन सुनिश्चित कर सकता है। मुझे एक नहीं मिला (ऐसा लगता है कि मैंने काफी कठिन नहीं देखा होगा) और इसलिए मैंने एक अमूर्त यूनिक्स डोमेन सॉकेट का उपयोग करके लिनक्स में अपने स्वयं के छद्म नाम म्यूटेक्स को लागू किया। उस सॉकेट में केवल एक ही बाइंड() सफल होगा। दूसरी अच्छी बात यह है कि यदि प्रक्रिया मर जाती है तो ओएस अमूर्त यूनिक्स डोमेन सॉकेट को साफ़ कर देगा और इस प्रकार सॉकेट को स्वयं साफ़ नहीं करेगा।दुर्भाग्यवश मुझे इस छद्म म्यूटेक्स पर उपलब्ध होने के लिए "प्रतीक्षा" करने का कोई भी तरीका नहीं है।

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

सभी लेकिन पहले बाइंड() EADDRINUSE की इरनो के साथ असफल हो जाएंगे।

// Create an abstract socket to use as a mutex.        

int err; 
int mutex_sock = socket(AF_UNIX, SOCK_STREAM, 0); 
if (mutex_sock == -1) 
    { 
    err = errno; 
    printf("main, failed creating mutex socket: %s\n", 
      get_error_string(errno, error_string, sizeof(error_string))); 
    log_event(LOG_LEVEL_ERROR, "main, failed creating mutex socket: " 
      "%s", get_error_string(errno, error_string, 
      sizeof(error_string))); 
    errno = err; 
    goto done; 
    } 

// Bind to abstract socket. We use this as a sort of named mutex.   

struct sockaddr_un addr; 
memset(&addr, 0, sizeof(addr)); 
addr.sun_family = AF_UNIX; 
strncpy(addr.sun_path + 1, socket_name, sizeof(addr.sun_path) - 2); 
result = bind(mutex_sock, (struct sockaddr*) &addr, sizeof(addr)); 
if (result == -1) 
    { 
    err = errno; 
    if (errno == EADDRINUSE) 
     { 
     printf("main, failed bind to mutex socket: %s. " 
       "Another instance must be running.\n", 
       get_error_string(errno, 
       error_string, sizeof(error_string))); 
     log_event(LOG_LEVEL_ERROR, "main, failed bind to mutex socket: " 
       "%s. " 
       "Another instance must be running.", 
       get_error_string(errno, 
       error_string, sizeof(error_string))); 
     } 
    else 
     { 
     printf("main, failed bind to mutex socket: %s\n", 
       get_error_string(errno, error_string, 
       sizeof(error_string))); 
     log_event(LOG_LEVEL_ERROR, "main, failed bind to mutex socket: %s", 
       get_error_string(errno, error_string, 
       sizeof(error_string))); 
     } 
    errno = err; 
    goto done; 
    } 

धन्यवाद, निक

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