न्यूनतम रननीय उदाहरण
Brk () सिस्टम कॉल क्या करता है?
गिरी को बताता है कि आप उसे पढ़ने और लिखने के लिए स्मृति के एक सन्निहित भाग को लिखते हैं जिसे ढेर कहा जाता है।
यदि आप नहीं पूछते हैं, तो यह आपको अलग कर सकता है।
इसके बिना brk:
#define _GNU_SOURCE
#include <unistd.h>
int main(void) {
/* Get the first address beyond the end of the heap. */
void *b = sbrk(0);
int *p = (int *)b;
/* May segfault because it is outside of the heap. */
*p = 1;
return 0;
}
के साथ brk:
#define _GNU_SOURCE
#include <assert.h>
#include <unistd.h>
int main(void) {
void *b = sbrk(0);
int *p = (int *)b;
/* Move it 2 ints forward */
brk(p + 2);
/* Use the ints. */
*p = 1;
*(p + 1) = 2;
assert(*p == 1);
assert(*(p + 1) == 2);
/* Deallocate back. */
brk(b);
return 0;
}
गिटहब ऊपर ।
उपरोक्त एक नया पृष्ठ हिट नहीं हो सकता है और बिना सीगफॉल्ट के भी नहीं हो सकता है brk, इसलिए यहां एक अधिक आक्रामक संस्करण है जो 16MiB आवंटित करता है और इसके बिना सीगफॉल्ट की संभावना है brk:
#define _GNU_SOURCE
#include <assert.h>
#include <unistd.h>
int main(void) {
void *b;
char *p, *end;
b = sbrk(0);
p = (char *)b;
end = p + 0x1000000;
brk(end);
while (p < end) {
*(p++) = 1;
}
brk(b);
return 0;
}
उबंटू 18.04 पर परीक्षण किया गया।
वर्चुअल एड्रेस स्पेस विज़ुअलाइज़ेशन
इससे पहले brk:
+------+ <-- Heap Start == Heap End
के बाद brk(p + 2):
+------+ <-- Heap Start + 2 * sizof(int) == Heap End
| |
| You can now write your ints
| in this memory area.
| |
+------+ <-- Heap Start
के बाद brk(b):
+------+ <-- Heap Start == Heap End
एड्रेस स्पेस को बेहतर तरीके से समझने के लिए, आपको पेजिंग से खुद को परिचित करना चाहिए: x86 पेजिंग कैसे काम करता है?।
हम क्यों की जरूरत है दोनों करते हैं brkऔर sbrk?
brk के साथ लागू किया जा सकता है sbrk + ऑफसेट गणना के , दोनों सिर्फ सुविधा के लिए मौजूद हैं।
बैकएंड में, लिनक्स कर्नेल v5.0 में एक सिंगल सिस्टम कॉल brkहै जिसका उपयोग दोनों को लागू करने के लिए किया जाता है: https://github.com/torvalds/linux/blob/v5.0/arch/x86/entry/syscalls_syscall_64। tbl # L23
12 common brk __x64_sys_brk
है brkPOSIX?
brk POSIX हुआ करता था, लेकिन POSIX 2001 में इसे हटा दिया गया, इस प्रकार इसकी आवश्यकता थी _GNU_SOURCE ग्लिबक रैपर तक पहुंचने की ।
परिचय के कारण हटाने की संभावना है mmap , जो एक सुपरसेट है जो कई रेंज को आवंटित करने और अधिक आवंटन विकल्प की अनुमति देता है।
मुझे लगता है कि कोई वैध मामला नहीं है जहां आपको brkइसके बजाय mallocया mmapआजकल का उपयोग करना चाहिए ।
brk बनाम malloc
brk लागू करने की एक पुरानी संभावना है malloc ।
mmapवर्तमान में लागू करने के लिए वर्तमान में उपयोग किए जाने वाले सभी POSIX सिस्टम की संभावना नए शक्तिशाली रूप से अधिक शक्तिशाली तंत्र है malloc। यहाँ एक न्यूनतम रननेबल mmapमेमोरी आवंटन उदाहरण है ।
क्या मैं मिश्रण brkऔर मालॉक कर सकता हूं ?
यदि आपके mallocसाथ कार्यान्वित किया जाता है brk, तो मुझे पता नहीं है कि कैसे संभवत: चीजों को उड़ा नहीं सकता है, क्योंकि brkकेवल स्मृति की एक सीमा होती है।
हालाँकि मुझे इसके बारे में कुछ भी पता नहीं चल पाया है, उदाहरण के लिए:
चीजें संभवत: वहीं काम करेंगी जो मुझे लगता है mmapकि संभावना है malloc।
यह सभी देखें:
और जानकारी
आंतरिक रूप से, कर्नेल यह तय करता है कि क्या इस प्रक्रिया में बहुत अधिक मेमोरी और इयरमार्क्स मेमोरी पेज हो सकते हैं उस उपयोग के लिए ।
यह बताता है कि ढेर की तुलना कैसे की जाती है: x86 असेंबली में रजिस्टरों पर उपयोग किए जाने वाले पुश / पॉप निर्देशों का क्या कार्य है?