2008-10-08 24 views
8

Tôi đang tìm kiếm các nguyên tắc cơ bản để lưu trữ trạng thái của chương trình thực thi vào đĩa và đưa nó trở lại. Trong thiết kế hiện tại mà chúng ta có, mỗi đối tượng (là một thingy mức C với các danh sách con trỏ hàm, loại định hướng đối tượng được tạo ở mức độ thấp - và có những lý do rất tốt để làm theo cách này) sẽ là được gọi để xuất trạng thái rõ ràng của nó sang định dạng có thể ghi và có thể chỉnh sửa. Thuộc tính quan trọng để thực hiện công việc này là tất cả các trạng thái liên quan đến một đối tượng thực sự được đóng gói trong các cấu trúc dữ liệu đối tượng.Serialization của các đối tượng: không có trạng thái thread có thể được tham gia, phải không?

Có các giải pháp khác mà bạn làm việc với các đối tượng đang hoạt động, trong đó có một chuỗi cấp người dùng được đính kèm với một số đối tượng. Và do đó, bộ đếm chương trình, nội dung đăng ký và nội dung ngăn xếp đột nhiên trở thành một phần của trạng thái chương trình. Theo như tôi có thể thấy, không có cách nào tốt để serialize những thứ như vậy vào đĩa tại một điểm tùy ý trong thời gian. Các chủ đề phải đi công viên mình trong một số trạng thái đặc biệt mà không có gì được đại diện bởi bộ đếm chương trình et al, và do đó về cơ bản "lưu" trạng thái máy trạng thái thực thi của chúng cho trạng thái đối tượng rõ ràng.

Tôi đã xem xét một loạt các thư viện tuần tự hóa và theo như tôi có thể nói đây là một thuộc tính chung.

Câu hỏi cốt lõi là: Hoặc thực sự không phải vậy? Có lưu/khôi phục lại các giải pháp trên mạng có thể bao gồm trạng thái luồng, về mặt mã nguồn của một chuỗi đang thực thi không?

Lưu ý rằng lưu toàn bộ trạng thái hệ thống trong máy ảo không được tính, điều đó không thực sự tuần tự hóa trạng thái, mà chỉ đóng băng máy và di chuyển nó. Đó là một giải pháp rõ ràng, nhưng một chút nặng nề hầu hết thời gian.

Một số câu hỏi làm rõ rằng tôi không đủ rõ ràng trong việc giải thích ý tưởng về cách chúng tôi làm việc. Chúng tôi đang làm việc trên một hệ thống mô phỏng, với các quy tắc rất nghiêm ngặt cho mã chạy bên trong nó được phép được viết. Đặc biệt, chúng ta tạo ra một sự phân chia hoàn toàn giữa việc xây dựng đối tượng và trạng thái đối tượng. Các con trỏ hàm giao diện được tạo lại mỗi lần bạn thiết lập hệ thống và không phải là một phần của trạng thái. Nhà nước chỉ bao gồm các "thuộc tính" được chỉ định cụ thể mà mỗi hàm có một hàm get/set được định nghĩa để chuyển đổi giữa biểu diễn thời gian chạy nội bộ và biểu diễn lưu trữ. Đối với con trỏ giữa các đối tượng, tất cả chúng đều được chuyển đổi thành tên. Vì vậy, trong thiết kế của chúng tôi, một đối tượng có thể xuất hiện như thế này trong bộ nhớ:

Object foo { 
    value1: 0xff00ff00; 
    value2: 0x00ffeedd; 
    next_guy_in_chain: bar; 
} 

Object bar { 
    next_guy_in_chain: null; 
} 

Danh sách liên kết không bao giờ thực sự có mặt trong cấu trúc mô phỏng, mỗi đối tượng đại diện cho một đơn vị phần cứng.

Vấn đề là một số người muốn làm điều này, nhưng cũng có chủ đề như một cách để mã hành vi. "Hành vi" ở đây thực sự là đột biến của trạng thái của các đơn vị mô phỏng. Về cơ bản, thiết kế chúng tôi đã nói rằng tất cả những thay đổi như vậy phải được thực hiện trong các hoạt động hoàn chỉnh nguyên tử được gọi, thực hiện công việc của họ và quay trở lại. Tất cả các trạng thái được lưu trữ trong các đối tượng. Bạn có một mô hình phản ứng, hoặc nó có thể được gọi là "chạy đến hoàn thành", hoặc "sự kiện điều khiển".

Cách suy nghĩ khác về việc này là để các đối tượng có chuỗi hoạt động hoạt động trên chúng, nằm trong vòng lặp vĩnh cửu giống như các luồng Unix cổ điển và không bao giờ chấm dứt. Đây là trường hợp mà tôi đang cố gắng để xem nếu nó có thể được lưu trữ hợp lý vào đĩa, nhưng nó không có vẻ như đó là khả thi mà không interposing một VM bên dưới.

Cập nhật, tháng 10 năm 2009: Một giấy liên quan đến điều này đã được xuất bản tại hội nghị FDL năm 2009, xem this paper về điểm kiểm tra và SystemC.

Trả lời

0

Bạn KHÔNG nên cố gắng tuần tự hóa trạng thái mà chương trình của bạn có đĩa. Vì chương trình của bạn sẽ không bao giờ có toàn quyền kiểm soát 'trạng thái trừ khi được hệ điều hành cho phép, trong trường hợp đó ... nó là một phần của hệ điều hành.

Bạn không thể đảm bảo rằng con trỏ tới vị trí bộ nhớ ảo sẽ trỏ đến cùng một vị trí bộ nhớ ảo (ngoại trừ các thuộc tính như bắt đầu/kết thúc, bắt đầu xếp chồng), vì chương trình 'sự lựa chọn cho bộ nhớ ảo là không xác định. Các trang bạn yêu cầu từ hệ điều hành thông qua sbrk hoặc các giao diện cấp cao hơn như malloc sẽ bắt đầu ở bất kỳ đâu.

tốt hơn:

  • Mã sạch và kiểm tra thiết kế của bạn: tính chất tiểu bang nào là một phần của nó?
  • Không sử dụng ngôn ngữ cấp thấp như vậy, vì chi phí trong việc tạo ra những gì bạn cố gắng làm không đáng để nhận kết quả.
  • Nếu bạn phải sử dụng C, hãy xem xét các phương tiện để làm cho cuộc sống của bạn dễ dàng nhất có thể (xem xét toán tử offsetof và các thuộc tính có thành viên đầu tiên bắt đầu tại offset 0).

Tôi nghi ngờ bạn muốn tắt thời gian phát triển để sắp xếp/xác định cấu trúc dữ liệu cụ thể, chẳng hạn như danh sách được liên kết. Hãy yên tâm, những gì bạn đang cố gắng làm là không tầm thường và nó hoạt động nhiều hơn. Nếu bạn khăng khăng làm như vậy, hãy cân nhắc xem xét mã quản lý bộ nhớ của hệ điều hành của bạn và vào các cơ chế phân trang của hệ điều hành. ;-)

CHỈNH SỬA do câu hỏi được thêm vào: Thiết kế bạn nêu có vẻ giống như một số loại máy trạng thái; các thuộc tính đối tượng được thiết lập sao cho chúng có thể tuần tự hóa được, các con trỏ hàm có thể được phục hồi.

Thứ nhất, liên quan đến bang chủ đề trong các đối tượng: những vấn đề duy nhất nếu có thể được đặc trưng đồng thời lập trình các vấn đề như điều kiện chủng tộc, vv Nếu đó là trường hợp, bạn cần chức năng thread-đồng bộ hóa, chẳng hạn như mutexes, Cột , vv Sau đó, bạn có thể truy cập vào các thuộc tính để tuần tự hóa/deserialize và được an toàn bất cứ lúc nào.

Thứ hai, liên quan đến thiết lập đối tượng: trông thật tuyệt, không chắc chắn nếu bạn đang có biểu diễn nhị phân hoặc đối tượng khác. Giả sử nhị phân: bạn có thể tuần tự hóa chúng một cách dễ dàng nếu bạn có thể đại diện cho các cấu trúc thực tế trong bộ nhớ (mà là một chút chi phí mã hóa). Chèn một số loại giá trị ID lớp ở đầu các đối tượng và có bảng tra cứu trỏ đến trang phục thực tế. Hãy xem các byte sizeof (id) đầu tiên và bạn biết loại cấu trúc nào bạn có. Thế thì bạn sẽ biết cấu trúc nào đang nằm ở đó.

Khi tuần tự hóa/deserializing, tiếp cận vấn đề như thế này: bạn có thể tra chiều dài của cấu trúc giả định (không có khoảng cách giữa các thành viên), phân bổ kích thước đó và đọc/ghi các thành viên sau cái kia. Hãy suy nghĩ offsetof hoặc, nếu trình biên dịch của bạn hỗ trợ nó, chỉ cần sử dụng cấu trúc đóng gói.

CHỈNH SỬA do câu hỏi cốt lõi đậm :-) Không, không có gì; không phải cho C.

+0

Vâng, các chủ đề ở đây là những thứ trong cái gọi là SystemC, về cơ bản hợp tác không ưu tiên luồng bằng cách sử dụng quickthreads hoặc Windows sợi. Trong một chuỗi hệ điều hành duy nhất. – jakobengblom2

0

Dường như bạn muốn có một số closure bằng C++.Như bạn đã chỉ ra không có cơ chế được xây dựng trong ngôn ngữ để cho phép bạn làm điều này. Theo như tôi biết điều này về cơ bản là không thể làm một cách hoàn toàn chung chung. Nói chung rất khó để làm trong một ngôn ngữ mà không có một máy ảo. Bạn có thể giả mạo nó bằng cách làm một cái gì đó như bạn đã gợi ý về cơ bản tạo ra một đối tượng đóng cửa duy trì môi trường thực hiện/nhà nước. Sau đó, có này serialize chính nó khi nó đang ở trong một nhà nước được biết đến.

Bạn cũng sẽ gặp sự cố với các con trỏ hàm của mình. Các chức năng có thể được nạp vào các địa chỉ bộ nhớ khác nhau trên mỗi tải.

1

Nó thực sự giống như tiết kiệm trạng thái của một máy ảo và có thể khôi phục lại nó theo cùng một cách chính xác là chính xác những gì bạn muốn.

Nếu tất cả những gì bạn cần là có thể bắt đầu chương trình đang chạy với cùng dữ liệu mà thao tác trước đó đang sử dụng, thì bạn chỉ cần lưu và khôi phục dữ liệu liên tục, trạng thái chính xác của mỗi luồng không thực sự vấn đề, vì nó sẽ thay đổi nhanh chóng như vậy - và địa chỉ thực sự của mọi thứ sẽ khác nhau vào lần sau. Sử dụng một cơ sở dữ liệu sẽ cung cấp cho bạn khả năng này anyways.

+0

Không hoàn toàn: bạn cũng phải có khả năng khôi phục trạng thái thành một triển khai khác, ví dụ, trên một loại máy chủ khác. Trạng thái luồng không thành vấn đề, nếu nó được sử dụng để mã hóa một số máy trạng thái như giao thức bus, ví dụ. – jakobengblom2

2

Tôi không nghĩ rằng việc tuần tự hóa "một số chủ đề" của chương trình có thể hoạt động, vì bạn sẽ gặp vấn đề với đồng bộ hóa (một số vấn đề được mô tả ở đây http://java.sun.com/j2se/1.3/docs/guide/misc/threadPrimitiveDeprecation.html). Vì vậy, hãy kiên trì toàn bộ chương trình của bạn là cách duy nhất khả thi để có được trạng thái nhất quán.

Điều bạn có thể xem xét là sự kiên trì trực giao. Có một số việc triển khai nguyên mẫu:

http://research.sun.com/forest/COM.Sun.Labs.Forest.doc.external_www.PJava.main.html

http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.17.7429

Nhưng không ai trong số họ được duy trì nữa hay đã đạt được rất nhiều hấp dẫn (afaik). Tôi đoán checkpointing không phải là giải pháp tốt nhất sau khi tất cả. Trong dự án của riêng tôi http://www.siebengeisslein.org Tôi đang thử cách tiếp cận sử dụng giao dịch nhẹ để gửi một sự kiện để trạng thái luồng không được duy trì (kể từ khi kết thúc giao dịch, chuỗi callstack bị trống một lần nữa và nếu một thao tác dừng lại giữa giao dịch, mọi thứ được cuộn lại, do đó, chuỗi callstack cũng không quan trọng). Bạn có thể thực hiện một cái gì đó tương tự với bất kỳ OODBMS nào.

Một cách khác để xem xét mọi thứ là sự tiếp tục (http://en.wikipedia.org/wiki/Continuation, http://jauvm.blogspot.com/). Chúng là một cách để tạm ngưng thực hiện tại các vị trí mã đã xác định (nhưng chúng không nhất thiết phải duy trì trạng thái luồng).

Tôi hy vọng điều này sẽ cung cấp cho bạn một số điểm khởi đầu (nhưng không có giải pháp sẵn sàng để sử dụng cho afaik này).

EDIT: Sau khi đọc các giải thích của bạn: Bạn chắc chắn nên xem xét OODBMS. Gửi mỗi sự kiện trong giao dịch của riêng mình và không quan tâm đến chủ đề.

0

Tôi xem trạng thái luồng là chi tiết triển khai có thể không phù hợp để được đăng. Bạn muốn lưu trạng thái của các đối tượng của mình - không nhất thiết là cách chúng trở thành cách thức của chúng.

Ví dụ về lý do bạn muốn thực hiện phương pháp này, hãy xem xét nâng cấp không cần thiết. Nếu bạn đang chạy phiên bản N của ứng dụng và muốn nâng cấp lên phiên bản N + 1, bạn có thể làm như vậy bằng cách sử dụng tuần tự hóa đối tượng. Tuy nhiên, các "phiên bản N + 1" chủ đề sẽ ot khác với chủ đề phiên bản N.

1

Một cách tiếp cận tốt hơn là cố gắng sắp xếp lại trạng thái chương trình sẽ là triển khai Crash Only Software bằng cách kiểm tra dữ liệu. Cách kiểm tra dữ liệu của bạn sẽ phụ thuộc vào việc triển khai và vấn đề miền của bạn.

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