कल एक प्रश्न के बारे में दोगुना-चेक लॉकिंग ने विचारों की एक श्रृंखला शुरू की जिसने मुझे एक साधारण स्थिति के बारे में अनिश्चित छोड़ दिया। निम्न कोड में, क्या "सिंक में अब नहीं" के printf
को हिट करना संभव है? इस सरल उदाहरण में, मान एक ही कैश लाइन पर होंगे, इसलिए मुझे लगता है कि यह कम संभावना होगी (संभावना है कि 0% से शुरू होने की संभावना है)।क्या WaitForSingleObject मेमोरी बैरियर के रूप में सेवा करता है?
यदि उत्तर है, "नहीं, यह संभव नहीं है।", तो मेरा अनुवर्ती प्रश्न, बल्कि अनुमानित रूप से है: क्यों नहीं? जब तक मैंने अपने विचारों को कल बहु-थ्रेडिंग धुरी के चारों ओर घिरा और लपेट लिया, तब तक मुझे लगता है कि कोड सुरक्षित होगा। लेकिन अब मैं सोच रहा हूं कि pa
या pb
चर के लिए कैश से पढ़ा जाने वाला एक स्टेल क्या रोकता है। और इससे कोई फर्क नहीं पड़ता कि pa, pb
ने malloc'd स्मृति की बजाय सरल वैश्विक पूर्णांक चर की ओर इशारा किया है? क्या WaitForSingleObject कॉल मेमोरी बाधा प्रदान करता है? या पॉइंटर्स अस्थिर घोषित किया जाना चाहिए? इतने सारे प्रश्न, बहुत कम वाक्यों।
अद्यतन: मैं अंत में स्थित जानकारी विशेष रूप से कहा गया है कि कि कार्यों कि तुल्यकालन वस्तुओं संकेत का उपयोग करते हैं memory barriers। यह स्पष्ट होना चाहिए था, लेकिन मुझे एक निश्चित जवाब खोजने में परेशानी हो रही थी। तो मैं एक बार फिर खुद को विश्वास में डाल सकता हूं कि मैं इसे सब समझता हूं।
int i1 = 0;
int i2 = 0;
int reads = 0;
int done = 0;
int *pa = NULL;
int *pb = NULL;
HANDLE hSync = NULL;
DWORD WriteThread(LPVOID pvParam)
{
while(!done)
{
WaitForSingleObject(hSync, INFINITE);
(*pa)++;
(*pb)++;
ReleaseSemaphore(hSync, 1, NULL);
}
return 0;
}
DWORD ReadThread(LPVOID pvParam)
{
while(!done)
{
WaitForSingleObject(hSync, INFINITE);
if (*pa != *pb)
{
printf("No longer in sync: %d, %d\n", *pa, *pb);
exit(1);
}
ReleaseSemaphore(hSync, 1, NULL);
reads++;
}
return 0;
}
int main(int argc, char* argv[])
{
DWORD dwID;
// malloc'd memory
pa = (int*)malloc(sizeof(int));
pb = (int*)malloc(sizeof(int));
// Is a simple global variable different?
//pa = &i1;
//pb = &i2;
*pa = 0;
*pb = 0;
hSync = CreateSemaphore(NULL, 1, 1, NULL);
CreateThread(NULL, 0, WriteThread, NULL, 0, &dwID);
CreateThread(NULL, 0, ReadThread, NULL, 0, &dwID);
while (*pa < 1000000)
Sleep(1);
done = 1;
return 0;
}
+1 ठीक वही जो मैं कहने जा रहा था। – tony
जानकारी के लिए धन्यवाद। क्या आपको एक लिंक पता है जो प्रतीक्षा कार्यों और स्मृति बाधाओं पर चर्चा करता है। यही वह है जिसे मैं ढूंढ रहा था और इसे नहीं देखा। यह काफी संभव है कि मैं सिर्फ अंधा हूं और कुछ स्पष्ट याद किया। –
आप अंधे नहीं हैं; प्रासंगिक जानकारी ऑनलाइन खोजना मुश्किल है। एमएसडीएन http://msdn.microsoft.com/en-us/library/ms686355%28VS.85%29.aspx पर एक उचित रूप से अच्छा अवलोकन प्रदान करता है। –