2010-01-16 62 views
7

Tôi có thể đọc chi tiết về một số chi tiết tại sbrk() ở đâu?Làm thế nào để sbrk() làm việc trong C++?

Làm thế nào nó hoạt động chính xác?

Trong trường hợp nào tôi muốn sử dụng sbrk() thay vìvà new() cồng kềnh?

btw, mở rộng cho sbrk() là gì?

Trả lời

8

Hãy xem the specification for brk/sbrk.

Cuộc gọi về cơ bản yêu cầu hệ điều hành phân bổ thêm bộ nhớ cho ứng dụng bằng cách tăng "giá trị ngắt" trước đó cho một số tiền nhất định. Số tiền này (tham số đầu tiên) là số lượng bộ nhớ bổ sung mà ứng dụng của bạn nhận được.

Hầu hết các triển khai thực hiện thô sơ trên nền hệ thống sbrk gọi để nhận các khối bộ nhớ mà chúng phân chia và theo dõi. Hàm mmap thường được chấp nhận như một sự lựa chọn tốt hơn (đó là lý do tại sao mallocs như dlmalloc hỗ trợ cả với #ifdef).

Đối với "làm thế nào nó hoạt động", một sbrk ở mức đơn giản nhất của nó có thể trông giống như thế này:

uintptr_t current_break; // Some global variable for your application. 
         // This would probably be properly tracked by the OS for the process 
void *sbrk(intptr_t incr) 
{ 
    uintptr_t old_break = current_break; 
    current_break += incr; 
    return (void*) old_break; 
} 

hệ điều hành hiện đại sẽ làm gì xa hơn, chẳng hạn như các trang bản đồ vào không gian địa chỉ và thêm thông tin theo dõi cho mỗi khối bộ nhớ được cấp phát.

+0

Lưu ý rằng các chức năng được đánh dấu 'LEGACY' trong tham chiếu; nếu bạn đi đến đặc điểm kỹ thuật SUS hiện tại (http://www.opengroup.org/onlinepubs/9699919799/toc.htm), chúng (brk, sbrk) không có mặt. –

+0

Điểm tốt - việc sử dụng các chức năng như vậy cũng có thể gây ra các vấn đề về tính di động nếu việc triển khai quyết định không quan tâm đến khả năng tương thích ngược. –

4

sbrk là khá nhiều lỗi thời, những ngày này bạn sẽ sử dụng mmap để ánh xạ một số trang ra khỏi/dev/zero. Nó chắc chắn không phải là thứ bạn sử dụng thay vì malloc và bạn bè, đó là một cách để thực hiện chúng. Ngoài ra, tất nhiên, nó chỉ tồn tại trên các hệ điều hành dựa trên posix quan tâm đến khả năng tương thích ngược với mã cổ.

Nếu bạn thấy Malloc và New quá cồng kềnh, bạn nên nhìn vào bộ sưu tập rác thay vì ... nhưng hãy cẩn thận, có một chi phí hiệu năng tiềm năng cho điều đó, vì vậy bạn cần phải hiểu những gì bạn đang làm.

0

Điều này phụ thuộc vào ý bạn của malloc là "Cồng kềnh". sbrk thường không được sử dụng trực tiếp nữa, trừ khi bạn đang thực hiện bộ cấp phát bộ nhớ của riêng bạn: IE, toán tử ghi đè "mới". Thậm chí sau đó tôi có thể sử dụng malloc để cho tôi bộ nhớ ban đầu của mình.

Nếu bạn muốn xem cách triển khai malloc() trên đầu trang của sbrk(), hãy xem http://web.ics.purdue.edu/~cs354/labs/lab6/ là một bài tập thực hành.

Trên hệ thống hiện đại, bạn không nên chạm vào giao diện này. Vì bạn đang gọi malloc và mới cồng kềnh, tôi nghi ngờ bạn không có tất cả các kinh nghiệm cần thiết để sử dụng sbrk an toàn và đúng cách cho mã của bạn.

1

Bạn không bao giờ muốn sử dụng sbrk thay vì malloc hoặc free. Nó không di động và thường chỉ được sử dụng bởi những người triển khai thư viện C chuẩn hoặc trong trường hợp không có sẵn.Nó được mô tả khá tốt trong nó man page:

Mô tả

brk() thiết lập cuối của đoạn dữ liệu với giá trị được xác định bởi end_data_segment, khi giá trị đó là hợp lý, hệ thống làm có đủ bộ nhớ và quá trình không vượt quá kích thước dữ liệu tối đa của nó (xem setrlimit (2)).

sbrk() tăng dữ liệu của chương trình không gian bằng byte tăng. sbrk() không phải là một cuộc gọi hệ thống, nó chỉ là một thư viện C trình bao bọc. Gọi sbrk() với số tăng của 0 có thể được sử dụng để tìm vị trí hiện tại của thời gian ngắt chương trình .

Return Value

Mở thành công, brk() trả về zero, và sbrk() trả về một con trỏ đến sự bắt đầu của khu vực mới. Lỗi, -1 được trả lại và errno được đặt thành ENOMEM.

Cuối cùng, mallocfree không cồng kềnh - họ là những cách tiêu chuẩn để phân bổ và giải phóng bộ nhớ trong C. Thậm chí nếu bạn muốn thực hiện cấp phát bộ nhớ riêng của bạn, cách tốt nhất là chỉ cần sử dụng mallocfree làm cơ sở - một cách tiếp cận phổ biến là phân bổ một phần lớn tại một thời điểm với malloc và cung cấp cấp phát bộ nhớ từ nó (đây là những gì suballocators, hoặc bơi, thường thực hiện)


Re nguồn gốc của tên sbrk (hoặc của nó anh em họ brk), nó có thể h ave một cái gì đó để làm với thực tế là sự kết thúc của đống được đánh dấu bằng một con trỏ được gọi là "phá vỡ". Heap bắt đầu ngay sau phân đoạn BSS và thường tăng lên theo hướng ngăn xếp.

1

Bạn đã gắn thẻ C++ này tại sao bạn sử dụng malloc (cồng kềnh) thay vì mới? Tôi không chắc chắn những gì là cồng kềnh về malloc trong mọi trường hợp; nội bộ có thể như vậy, nhưng tại sao bạn sẽ quan tâm? Và nếu bạn đã quan tâm (vì lý do xác định ví dụ), bạn có thể phân bổ một hồ bơi lớn và thực hiện cấp phát của riêng bạn cho hồ bơi đó. Trong C++ tất nhiên bạn có thể quá tải toán tử mới để thực hiện điều đó.

sbrk được sử dụng để dán thư viện C vào quản lý bộ nhớ hệ điều hành bên dưới của hệ thống. Vì vậy, thực hiện cuộc gọi OS thay vì sử dụng sbrk(). Như thế nào nó hoạt động, đó là hệ thống phụ thuộc. Ví dụ, nếu bạn đang sử dụng thư viện Newlib C (thường được sử dụng trên các hệ thống nhúng 'kim loại trần' với trình biên dịch GNU), bạn phải implement sbrk yourself, vì vậy nó hoạt động như thế nào trong các trường hợp đó tùy thuộc vào bạn. hành vi mở rộng vùng heap hoặc thất bại.

Như bạn có thể thấy từ liên kết, nó không làm nhiều và sẽ là cực kỳ cồng kềnh để sử dụng trực tiếp - bạn có thể kết thúc gói nó trong tất cả các chức năng mà malloc và mới cung cấp trong mọi trường hợp.

Các vấn đề liên quan