2009-11-17 16 views
12

मैं लिनक्स चला रहा हूं, और मैं साझा लाइब्रेरी (.so) में समांतर फ़ंक्शन कॉल करने में सक्षम होना चाहता हूं, दुर्भाग्य से थ्रेडसेफ नहीं है (मुझे लगता है कि इसमें वैश्विक डेटास्ट्रक्चर हैं)।साझा लाइब्रेरी की कई प्रतियां लोड करें

प्रदर्शन कारणों से, मैं फ़ंक्शन कॉल को म्यूटेक्स में लपेटना नहीं चाहता हूं।

मैं 4 थ्रेड कहने के लिए क्या करना चाहता हूं, और उसी लाइब्रेरी की 4 प्रतियों को प्रक्रिया मेमोरी में लोड करना चाहता हूं। प्रत्येक थ्रेड फ़ंक्शन को लाइब्रेरी की अपनी प्रति में कॉल करता है।

दुर्भाग्य से, dlopen मुझे किसी भी पुस्तकालय के एक और उदाहरण को लोड करने की अनुमति नहीं देता है।

क्या किसी को भी किसी भी विधि के बारे में पता है जो मुझे पुस्तकालय को एक से अधिक बार लोड करने की अनुमति देगा? (.so फ़ाइल की 4 प्रतियां बनाने के अलावा, प्रत्येक एक अलग नाम के साथ)

+0

उन लोगों के लिए जिन्हें उदाहरण की आवश्यकता है, तुलना [लागू] [https://github.com/ikoryakovskiy/not_threadsafe_test) लागू की गई। – Ivan

उत्तर

6

धागे का उपयोग करने के बजाय, आप कई प्रक्रियाओं का उपयोग कर सकते हैं, प्रत्येक कार्य में से कुछ करते हैं। यह * निक्स पर बहुत आम है, और आमतौर पर कोड के लिए आसान है।

+2

मुझे कोड के लिए आसान नहीं पता है। निश्चित रूप से, 'फोर्क()' को कॉल करना हल्का आसान है, फिर यह एक धागा लॉन्च करना है। लेकिन यदि आपको प्रक्रियाओं के बीच संवाद करने की आवश्यकता है, या प्रक्रियाओं के बीच डेटा साझा करना है तो आप आईपीसी, (साझा स्मृति, पाइप इत्यादि) की दुनिया में आते हैं, जो कोड के लिए तर्कसंगत रूप से अधिक जटिल है। –

+2

स्टार्टर्स के लिए, अपनी गैर-थ्रेड-सुरक्षित लाइब्रेरी का उपयोग करना आसान है। :) मुझे कोड को आसान लगता है क्योंकि डेडलॉक्स और संबंधित समस्याओं से बचना आसान है, लेकिन, हाँ, उनके संस्करण भी आईपीसी में हैं। –

+1

@ चार्ल्स - ओपी के उद्देश्य को देखते हुए, कई प्रक्रियाओं पर जाकर शायद उसका सबसे दर्दनाक विकल्प है। –

1

एक बुरा विचार की तरह लग रहा है। साझा पुस्तकालयों के साथ यह और भी संभव नहीं है क्योंकि यह स्थैतिक लोगों के साथ होगा।

आप शायद RTLD_LOCAL ध्वज के साथ dlopen() का उपयोग कर सकते हैं ताकि बाद में कॉल को डलोपेन को यह पहले से लोड नहीं किया जा सके और इसे वैसे ही काम कर सके जैसा आप चाहते हैं ... लेकिन यह अभी भी एक खराब डिज़ाइन विचार की तरह दिखता है। यदि आपके पास प्रदर्शन समस्याएं हैं तो यह एक ही लाइब्रेरी की कई प्रतियों के साथ अव्यवस्था मेमोरी से बेहतर होगा।

मैं या तो कई प्रक्रियाओं का उपयोग या म्यूटेक्स तरीके से जाने का सुझाव दूंगा, यह शायद अधिक कुशल है।

जैसा कि आप लिनक्स पर काम करते हैं, वहां भी अन्य दृष्टिकोण मौजूद हो सकते हैं यदि आप लाइब्रेरी के स्रोत कोड तक पहुंच सकते हैं, जैसे कि इसके प्रतीकों का नाम बदलने के लिए कई अलग-अलग उदाहरण हैं ... ठीक है, एक बार जब आप स्रोत प्राप्त कर सकते हैं लाइब्रेरी थ्रेड को सुरक्षित बनाने जैसे अन्य तरीके बनें।

0

यह पुस्तकालय क्या है? क्या यह कुछ बड़ा है? मैं सोच रहा हूं कि क्या आप लाइब्रेरी को किसी भी तरह से थ्रेडसेफ के रूप में ठीक नहीं कर पाएंगे, फिर लाइब्रेरी के थ्रेडसेफ संस्करण का उपयोग करके अपना कोड बनाएं। यह लाइब्रेरी के आकार पर निर्भर करता है, और इसमें क्या गड़बड़ है, लेकिन यदि आप लाइब्रेरी को ठीक कर सकते हैं, तो आप अपना ऐप अपनी इच्छानुसार बनाने में सक्षम होंगे, साथ ही साथ हर किसी की मदद करें।

+1

आप इसे गैर-थ्रेडसेफ एपीआई को उजागर करने की तरह क्यों कह रहे हैं कुछ गलत है और इसे ठीक करने की आवश्यकता है? थ्रेड-सुरक्षा गारंटी प्रदान करने के लिए दोनों व्यापार-बंद हैं, और नहीं। – ulidtko

+0

@ulidtko - मूल प्रश्न गैर-थ्रेडसेफ एपीआई का उपयोग इस तरीके से करने के बारे में है जहां थ्रेड सुरक्षा की कमी चीजों को तोड़ देगी। मूल पोस्टर के प्रयोजनों के लिए, लाइब्रेरी टूटा हुआ है। स्पष्ट रूप से गैर-थ्रेडसेफ एपीआई के साथ कोई समस्या नहीं है, लेकिन ओपी के लिए, लाइब्रेरी उपयोग करने योग्य होने से पहले फिक्स को बनाने की आवश्यकता है। यह एक संदर्भ बात है। –

+0

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

7

आप कर सकते हैं लोड इस तरह पुस्तकालय के कई स्वतंत्र प्रतियां:

#define _GNU_SOURCE 
#include <dlfcn.h> 
... 
void *handle = dlmopen(LM_ID_NEWLM, "/path/to/library.so", RTLD_NOW); 

अधिक जानकारी here

+0

हमारे बारे में कोई विचार गरीब विंडोज उपयोगकर्ता? यद्यपि यह लिनक्स के लिए बहुत उपयोगी है। – ibell

+0

यह विंडोज में भी लोड लाइब्रेरी और GetProcAddress के साथ काम करता है। मुझे लगता है कि आपको डीएलएल की कई भौतिक प्रतियों की आवश्यकता है, लेकिन यह ठीक काम करता है। –

+0

धन्यवाद! यह आपको एक सी ++ कक्षा में गैर-थ्रेड-सुरक्षित सी लाइब्रेरी लपेटने जैसी पागल करने देता है। वर्ग का नया() ऑपरेटर लाइब्रेरी को LM_ID_NEWLM से लोड करता है, फिर कक्षा में फ़ील्ड के रूप में लाइब्रेरी के फ़ंक्शन पॉइंटर्स को पॉप्युलेट करने के लिए dlsym() का उपयोग करता है। जैसा कि आप सामान्य रूप से एक सी ++ वर्ग की तरह प्रयोग करें। एक बुराई हैक का थोड़ा सा लेकिन यह तब काम करता है जब आप स्थिर साझा राज्य का उपयोग करने के लिए नरक की गहराई में किसी ऐसे व्यक्ति से कोड की 10,000 लाइनों को दोबारा नहीं करना चाहते हैं। – AdamIerymenko

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