2012-10-23 31 views
7

Tôi đang cố triển khai các sự kiện Windows rất đơn giản trong Linux. Chỉ cho kịch bản của tôi - 3 chủ đề, 1 chính và 2 phụ. Mỗi chủ đề thứ cấp tăng 1 sự kiện bằng SetEvent và chủ đề chính chờ đợi nó. Ví dụ:Windows Sự kiện triển khai trong Linux bằng các biến có điều kiện?

int main() 
{ 
    void* Events[2]; 
    Events[0] = CreateEvent(); 
    Events[1] = CreateEvent(); 

    pthread_start(Thread, Events[0]); 
    pthread_start(Thread, Events[1]); 

    WaitForMultipleObjects(2, Events, 30000) // 30 seconds timeout 

    return 0; 
} 

int* thread(void* Event) 
{ 
    // Do something 
    SetEvent(Event); 
    // Do something 
} 

Vì vậy, để triển khai, tôi sử dụng các biến điều kiện. Nhưng câu hỏi của tôi là - đây có phải là cách đúng đắn không? Hay tôi làm gì sai? Triển khai của tôi:

// Actually, this function return pointer to struct with mutex and cond 
// here i just simplified example 
void* CreateEvent(mutex, condition) 
{ 
    pthread_mutex_init(mutex, NULL); 
    pthread_cond_init(condition, NULL); 
} 

bool SetEvent (mutex, condition) 
{ 
    pthread_mutex_lock(mutex); 
    pthread_cond_signal(condition); 
    pthread_mutex_unlock(mutex); 
} 

int WaitForSingleObject(mutex, condition, timeout) 
{ 
    pthread_mutex_lock(mutex); 
    pthread_cond_timedwait(condition, mutex, timeout); 
    pthread_mutex_unlock(mutex); 
} 

// Call WaitForSingleObject for each event. 
// Yes, i know, that its a wrong way, but it should work in my example. 
int WaitForMultipleObjects(count, mutex[], condition[], timeout); 

Và tất cả có vẻ tốt, nhưng tôi nghĩ, sự cố đó sẽ xuất hiện khi tôi gọi hàm WaitFor .. trong chuỗi chính trước khi SetEvent trong chuỗi phụ sẽ được gọi. Trong Windows, nó hoạt động tốt, nhưng trong Linux - ý tưởng duy nhất được mô tả ở trên.

Có thể bạn cho tôi biết cách tốt hơn để giải quyết nó? Cảm ơn bạn.

UPD: Hết thời gian chờ là rất quan trọng, vì một trong các chuỗi phụ không thể vượt qua SetEvent().

+0

Chúng tôi có thư viện mã nguồn mở (gọi là MIT) được gọi là 'pevents', thực hiện các sự kiện thủ công và tự động đặt lại WIN32 trên Linux, và bao gồm cả hai dòng WaitForSingleObject và WaitForMultipleObjects: https://github.com/NeoSmart/PEvents –

+0

có thể trùng lặp của [sự kiện đặt lại hướng dẫn sử dụng cửa sổ giống như pthread] (http://stackoverflow.com/questions/178114/pthread-like-windows-manual-reset-event) – jww

Trả lời

1

Có câu hỏi tương tự trên stackoverflow đã: WaitForSingleObject and WaitForMultipleObjects equivalent in linux

Bên cạnh đó bạn có thể sử dụng Cột:

sem_t semOne ; 
sem_t semTwo ; 
sem_t semMain ; 

Trong chủ đề chính:

sem_init(semOne,0,0) ; 
sem_init(semTwo,0,0) ; 
sem_init(semMain,0,0) ; 

... 


sem_wait(&semMain); 

// Thread 1 
sem_wait(&semOne); 
sem_post(&semMain); 


// Thread 2 
sem_wait(&semTwo); 
sem_post(&semMain); 

Mô tả chi tiết và các ví dụ khác nhau có thể được tìm thấy tại đây: http://www.ibm.com/developerworks/linux/library/l-ipc2lin3/index.html

+0

Cảm ơn bạn, nhưng về thời gian chờ thì sao? Như tôi biết, semaphores không có nó. – DeniDoman

+0

Bạn có thể chỉ cần sử dụng sem_timedwait() thay vì sem_wait(). – codewarrior

+0

Tôi nghĩ rằng, các semaphores không thể timedwait ... Cảm ơn bạn) – DeniDoman

3

Căn này trên mô tả của WaitForSingleObject

Các WaitForSingleObject chức năng kiểm tra tình trạng hiện thời của đối tượng quy định. Nếu trạng thái của đối tượng không được định trước, thì chuỗi gọi sẽ chuyển sang trạng thái đợi cho đến khi đối tượng được báo hiệu hoặc khoảng thời gian hết hạn trôi qua.

Sự khác biệt giữa hành vi đó và mã là mã sẽ luôn chờ trên biến điều kiện vì nó không kiểm tra vị từ. Điều này giới thiệu các sự cố đồng bộ hóa giữa các cuộc gọi pthread_condt_timewaitpthread_cond_signal.

Các thành ngữ chung cho hệ thống báo một biến điều kiện là:

lock mutex 
set predicate 
unlock mutex 
signal condition variable 

Và khi chờ đợi một biến trạng:

lock mutex 
while (!predicate) 
{ 
    wait on condition variable 
} 
unlock mutex

Dựa trên những gì đang cố gắng để được thực hiện, một riêng biệt bool có thể là được sử dụng làm vị từ cho mỗi Event. Bằng cách giới thiệu một vị từ, WaitForSingleObject chỉ nên chờ trên biến điều kiện nếu Event chưa được báo hiệu. Mã sẽ trông giống như sau:

bool SetEvent (mutex, condition) 
{ 
    pthread_mutex_lock(mutex);     // lock mutex 
    bool& signalled = find_signal(condition); // find predicate 
    signalled = true;       // set predicate 
    pthread_mutex_unlock(mutex);    // unlock mutex 
    pthread_cond_signal(condition);   // signal condition variable 
} 

int WaitForSingleObject(mutex, condition, timeout) 
{ 
    pthread_mutex_lock(mutex);       // lock mutex 
    bool& signalled = find_signal(condition);   // find predicate 
    while (!signalled) 
    { 
     pthread_cond_timedwait(condition, mutex, timeout); 
    } 
    signalled = false;         // reset predicate 
    pthread_mutex_unlock(mutex);      // unlock mutex 
} 
+0

Cảm ơn bạn đã trợ giúp! – DeniDoman

0

Tôi nghĩ semaphore là giải pháp tốt hơn ở đây, vì nó có thể được sử dụng liên tiến trình. Bạn có thể bọc giao diện, nếu tên không được cung cấp, sau đó sử dụng pthread_ để khởi tạo nó cho quá trình sử dụng, có thể rút ngắn việc sử dụng tài nguyên, nhưng khi sử dụng tên, hãy thử sử dụng lệnh khởi tạo nó để sử dụng trong quá trình .

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