2012-10-31 27 views
14

Tôi có một chương trình Linux để sinh ra một số quy trình (fork) và giao tiếp thông qua POSIX Shared Memory. Tôi muốn có mỗi quá trình phân bổ một id (0-255). Ý định của tôi là đặt một bitvector trong khu vực bộ nhớ chia sẻ (khởi tạo bằng không) và nguyên tử so sánh và trao đổi một chút để phân bổ một id.C++ 11 interprocess atomics và mutexes

Có cách nào thân thiện với C++ 11 để thực hiện việc này không? Tôi có thể tạo một bitet nguyên tử không? Tôi có thể sử dụng mutex trên các quy trình không? Làm cách nào để đảm bảo rằng các nhà xây dựng được gọi một lần và chỉ một lần trên tất cả các quy trình?

+0

ngã ba trả về một pid của quá trình con để các phụ huynh proces, tại sao không chỉ sử dụng mà thay vì tạo ra một số khác? Hoặc tôi hiểu sai câu hỏi của bạn –

+0

@aleguna Bởi vì tôi muốn có một giá trị khác nhau, từ 0-255 và khi một quá trình rời khỏi chương trình này, nó sẽ miễn phí ID của nó sẽ được tái sử dụng. – dschatz

+0

@dschatz: "* Bởi vì tôi muốn có một giá trị khác nhau, từ 0-255 *" Điều đó không giải thích * tại sao * bạn cần điều đó. Đặc biệt là khi cơ chế PID rất nhiều * tốt hơn *. –

Trả lời

11

C++ 11 luồng nguyên thủy (mutexes, atomics, v.v.) là luồng nguyên thủy. Họ không biết gì về quy trình, và họ không phải là phương tiện để đạt được giao tiếp giữa các quá trình.

Vì tiêu chuẩn C++ 11 không đề cập đến các quy trình hoặc giao tiếp giữa các quá trình, hành vi của các nguyên thủy như vậy khi được đặt trong bộ nhớ chia sẻ quy trình (một tệp ánh xạ bộ nhớ, một số loại ngoài quy trình bộ nhớ được ánh xạ, vv) là không xác định.

+8

[atomics.lockfree] bao gồm "[Ghi chú: Các hoạt động không có khóa cũng nên không có địa chỉ. Đó là, các hoạt động nguyên tử trên cùng một vị trí bộ nhớ thông qua hai địa chỉ khác nhau sẽ giao tiếp nguyên tử. Việc triển khai sẽ không phụ thuộc vào bất kỳ Hạn chế này cho phép giao tiếp bằng bộ nhớ được ánh xạ vào một quá trình nhiều hơn một lần và bằng bộ nhớ được chia sẻ giữa hai tiến trình. - Lưu ý cuối cùng] " –

+0

Kính gửi @Nicol Bolas, câu trả lời của bạn rất tuyệt, nhưng tôi không thể tìm thấy ở bất cứ đâu hoặc bất kỳ cuốn sách viết về điều đó vì vậy tôi vẫn nhận được một số nhầm lẫn về việc sử dụng C++ 11 mutex trong bộ nhớ chia sẻ.(như tôi biết, mutex pthread là ok nếu sử dụng PTHREAD_PROCESS_SHARED) –

4

Bạn có thể sử dụng mutex bên trong khối bộ nhớ chia sẻ, nhưng mutex phải được khai báo là chia sẻ, do đó không phải là bất thường sử dụng mutexes bên trong chia sẻ bộ nhớ, u có thể làm cho lớp riêng, nó rất đơn giản:

class Mutex { 
private: 
    void *_handle; 
public: 
    Mutex(void *shmMemMutex, bool recursive =false,); 
    virtual ~Mutex(); 

    void lock(); 
    void unlock(); 
    bool tryLock(); 
}; 

Mutex::Mutex(void *shmMemMutex, bool recursive) 
{ 
    _handle = shmMemMutex; 
    pthread_mutexattr_t attr; 
    ::pthread_mutexattr_init(&attr); 
    ::pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); 
    ::pthread_mutexattr_settype(&attr, recursive ? PTHREAD_MUTEX_RECURSIVE_NP : PTHREAD_MUTEX_FAST_NP); 

    if (::pthread_mutex_init((pthread_mutex_t*)_handle, &attr) == -1) { 
     ::free(_handle); 
     throw ThreadException("Unable to create mutex"); 
    } 
} 
Mutex::~Mutex() 
{ 
    ::pthread_mutex_destroy((pthread_mutex_t*)_handle); 
} 
void Mutex::lock() 
{ 
    if (::pthread_mutex_lock((pthread_mutex_t*)_handle) != 0) { 
     throw ThreadException("Unable to lock mutex"); 
    } 
} 
void Mutex::unlock() 
{ 
    if (::pthread_mutex_unlock((pthread_mutex_t*)_handle) != 0) { 
     throw ThreadException("Unable to unlock mutex"); 
    } 
} 
bool Mutex::tryLock() 
{ 
    int tryResult = ::pthread_mutex_trylock((pthread_mutex_t*)_handle); 
    if (tryResult != 0) { 
     if (EBUSY == tryResult) return false; 
     throw ThreadException("Unable to lock mutex"); 
    } 
    return true; 
} 
Các vấn đề liên quan