2013-05-30 33 views
8

Tôi có một lớp tương đối phức tạp trong C++. Nó hoạt động hoàn hảo khi được sử dụng trong một quá trình. Tuy nhiên, bây giờ tôi muốn nhiều quy trình có thể chia sẻ một cá thể đối tượng của lớp này. Một tiến trình (Master) sẽ truy cập các chức năng đọc và ghi của đối tượng, trong khi 2 quy trình còn lại (Slave) sẽ chỉ sử dụng các hàm đọc. Tôi muốn sửa đổi lớp học càng ít càng tốt. Cho đến nay tôi đã coi những người độc thân và bộ nhớ chia sẻ, nhưng không có vẻ lý tưởng hay đơn giản. Đây là một ứng dụng nghiên cứu sẽ chỉ được tôi sử dụng trên Linux. Giải pháp đơn giản nhất có thể là gì?C++ chia sẻ đối tượng lớp đơn giữa nhiều quá trình

Cảm ơn bạn rất nhiều!

Chỉnh sửa: Để hoàn toàn rõ ràng, người hỏi muốn chia sẻ một đối tượng trên nhiều quy trình quy trình, không phải.

+1

tôi đã không sử dụng nó, nhưng bạn không đề cập được nhận thức của [Boost.Interprocess] (http: //www.boost. org/doc/libs/1_53_0/doc/html/interprocess.html). – BoBTFish

+0

Bạn có thể muốn tìm kiếm 'bộ nhớ chia sẻ'. [Đây là một câu hỏi về SO] (http://stackoverflow.com/questions/5656530/how-to-use-shared-memory-with-linux-in-c) nhưng đối với 'C' (phù thủy cũng có thể làm việc cho C++) – A4L

Trả lời

1

Một ý tưởng có thể là sử dụng ổ cắm hoặc thư viện ổ cắm để chia sẻ dữ liệu giữa các quy trình. Một thư viện có vẻ rất tiện dụng cho điều đó có thể là ØMQ. Bạn cũng có thể thử sử dụng Boost::Asio phức tạp hơn một chút.

Bạn có thể tìm thấy một ví dụ nhỏ cho ØMQ here.

0

Tôi nghĩ giải pháp mã hóa đơn giản nhất sẽ là một singleton với một mutex toàn cục (hoặc thể hiện lớp), mặc dù phần đơn lẻ là tùy chọn. Cá nhân tôi nghĩ rằng những người độc thân là một thành ngữ bị lạm dụng. Tùy thuộc vào bạn cho dù bạn nghĩ rằng đó là thiết kế tốt trong trường hợp này hay không. Thực sự, thêm mutex toàn cầu là tất cả những gì bạn cần.

Đối với phần interprocess, tôi khuyên bạn nên tăng cường.

http://www.boost.org/doc/libs/1_36_0/doc/html/interprocess/synchronization_mechanisms.html#interprocess.synchronization_mechanisms.semaphores.semaphores_interprocess_semaphores

3

Giao tiếp liên tiến trình không bao giờ đơn giản. Bạn có thể muốn sử dụng thư viện cho IPC/RPC và chỉ hiển thị hàm mà các nô lệ sử dụng để đọc dữ liệu chứ không phải toàn bộ lớp.

Tôi không thể cung cấp cho bạn bất kỳ đề xuất tốt nào vì tôi chưa bao giờ tìm thấy thư viện đơn giản và tôi không có nhiều kinh nghiệm về nó.

1

Một tùy chọn là có cả quy trình chính và quy trình tạo các phiên bản của cùng một đối tượng. Bởi vì quy trình tổng thể sẽ là người duy nhất để sửa đổi đối tượng 'chia sẻ' này, nó chỉ phải cảnh báo các quy trình nô lệ đối với bất kỳ thay đổi nào mà nó làm cho đối tượng 'được chia sẻ'. Để thực hiện việc này, bạn có thể thiết lập một hệ thống nhắn tin mà quy trình tổng thể sẽ sử dụng để truyền đạt các thay đổi cho đối tượng được chia sẻ với các quy trình nô lệ. Hạn chế ở đây là các quá trình nô lệ có thể tham chiếu đến đối tượng được chia sẻ khi nó không đồng bộ với chủ, nhưng đây là một vấn đề phổ biến trong việc sao chép. Ngoài ra, bạn có thể sử dụng lớp phủ RPC để làm cho các ứng dụng chính/nô lệ dễ dàng hơn trong việc phát triển/duy trì.

Tôi sẽ cố gắng cung cấp một ví dụ cấp cao về thiết kế này bên dưới.Tha thứ cho tôi vì sử dụng mã thực và mã psuedo song song; Tôi không muốn hoàn toàn mã này, nhưng cũng không muốn nó chỉ được tạo thành từ ý kiến ​​:)

Dưới đây là đối tượng chia sẻ của chúng tôi mà được định nghĩa trong cả mã master/slave

struct sharedobj { 
    int var1; 
}; 

Dưới đây là ví dụ về quy trình tổng thể cập nhật đối tượng được chia sẻ và truyền các thay đổi

int counter = 0; 
sharedobj mysharedobj; 
while(true){ 
    //update the local version first 
    mysharedobj.var1 = counter++; 

    //then call some function to push these changes to the slaves 
    updateSharedObj(mysharedobj); 
} 

Đây là chức năng truyền các thay đổi của chủ nhân cho nô lệ;

updatedSharedObj(sharedobj obj){ 

    //set up some sort of message that encompasses these changes 
    string msg = "var1:" + the string value of obj.var1; 

    //go through the set of slave processes 
    //if we've just done basic messaging, maybe we have a socket open for each process 
    while(socketit != socketlist.end()){ 

    //send message to slave 
    send(*socketit, msg.c_str(),msg.length(),0); 

    } 

} 

Và đây là mã nô lệ nhận các thay đổi này và cập nhật đối tượng 'được chia sẻ'; rất có thể chạy trong một thread khác để slave có thể chạy mà không cần phải dừng lại và kiểm tra các cập nhật đối tượng.

while(true){ 

    //wait on the socket for updates 
    read(mysock,msgbuf,msgbufsize,0); 

    //parse the msgbuf 
    int newv1 = the int value of var1 from the msg; 

    //if we're in another thread we need to synchronize access to the object between 
    //update thread and slave 
    pthread_mutex_lock(&objlock); 

    //update the value of var1 
    sharedobj.var1 = newv1; 

    //and release the lock 
    pthread_mutex_unlock(&objlock); 

}