2010-01-18 25 views

Trả lời

28

Thay vì đối tượng Java mà bạn sẽ sử dụng để chờ đợi/thông báo, bạn cần hai đối tượng: một mutex và một biến trạng . Chúng được khởi tạo với pthread_mutex_initpthread_cond_init.

Nơi bạn đã đồng bộ hóa trên đối tượng Java, sử dụng pthread_mutex_lockpthread_mutex_unlock (lưu ý rằng trong C, bạn phải tự mình ghép nối thủ công). Nếu bạn không cần phải chờ/thông báo, chỉ cần khóa/mở khóa, thì bạn không cần biến điều kiện, chỉ là mutex. Ghi nhớ rằng mutexes không nhất thiết phải "đệ quy", Điều này có nghĩa rằng nếu bạn đã giữ khóa, bạn không thể lấy nó một lần nữa trừ khi bạn thiết lập cờ init để nói rằng bạn muốn hành vi đó.

Nơi bạn sẽ gọi là java.lang.Object.wait, hãy gọi pthread_cond_wait hoặc pthread_cond_timedwait.

Nơi bạn sẽ gọi là java.lang.Object.notify, gọi pthread_cond_signal.

Nơi bạn sẽ gọi là java.lang.Object.notifyAll, gọi pthread_cond_broadcast. Như trong Java, có thể thực hiện các lần đánh thức giả mạo từ các chức năng chờ, vì vậy bạn cần một số điều kiện được đặt trước cuộc gọi để báo hiệu và kiểm tra sau khi cuộc gọi chờ, và bạn cần gọi tới số pthread_cond_wait trong vòng lặp. Như trong Java, mutex được phát hành trong khi bạn đang chờ đợi.

Không giống Java, nơi bạn không thể gọi notify trừ khi bạn giữ màn hình, bạn có thể thực sự gọi pthread_cond_signal mà không giữ mutex. Nó thường không giúp bạn đạt được bất cứ điều gì, mặc dù, và thường là một ý tưởng thực sự tồi tệ (bởi vì thông thường bạn muốn khóa - thiết lập điều kiện - tín hiệu - mở khóa). Vì vậy, tốt nhất là bỏ qua nó và đối xử với nó như Java.

Không thực sự nhiều hơn nữa, mẫu cơ bản giống với Java chứ không phải trùng hợp ngẫu nhiên. Do đọc tài liệu cho tất cả các chức năng, mặc dù, bởi vì có nhiều cờ và hành vi vui nhộn mà bạn muốn biết và/hoặc tránh.

Trong C++, bạn có thể làm tốt hơn một chút so với chỉ sử dụng API pthreads. Bạn ít nhất nên áp dụng RAII cho khóa/mở khóa mutex, nhưng tùy thuộc vào thư viện C++ nào bạn có thể sử dụng, bạn có thể nên sử dụng một trình bao bọc C++ - ish cho các hàm pthreads.

4

Sử dụng Condition Variables là một cách để thực hiện: những tính năng này có sẵn khi sử dụng thư viện pthread trong Linux (xem liên kết).

Một biến điều kiện là một biến loại pthread_cond_t và được sử dụng với các chức năng phù hợp với chờ đợi và sau đó, quá trình tiếp tục.

1

Nếu có, bạn có thể sử dụng semaphores POSIX. Thư viện pthread có mutexes, có thể làm việc cho bạn. Google nó ...

6

pthread_cond_wait và pthread_cond_signal thể được sử dụng để đồng bộ hóa dựa trên một điều kiện

2

Nếu bạn không quan tâm đến tính di động, Linux cung cấp eventfd, cung cấp cho bạn chính xác những gì bạn muốn. Mỗi eventfd giữ một bộ đếm nội bộ. Trong chế độ mặc định, đọc từ khối eventfd nếu bộ đếm là số không, nếu không sẽ trả về ngay lập tức. Viết cho nó sẽ thêm vào bộ đếm nội bộ.

Cuộc gọi chờ sẽ chỉ là uint64_t buf_a; read(event_fd, &buf_a, sizeof(buf_a));, trong đó buf phải là bộ đệm 8 byte. Để thông báo cho chuỗi chờ, bạn sẽ thực hiện uint64_t buf_b = 1; write(event_fd, &buf_b, sizeof(buf_b));.

6

Trong tiêu đề của bạn, bạn trộn lẫn C và C++ với nhau để tình cờ thành "C/C++". Tôi hy vọng, bạn không viết một chương trình mà là một hỗn hợp của cả hai.

Nếu bạn đang sử dụng C++ 11, bạn sẽ tìm thấy một giải pháp thay thế an toàn và dễ sử dụng hơn (trên hệ thống POSIX, thường sử dụng pthreads dưới mui xe) .

Bạn có thể sử dụng std::condition_variable + std::mutex để chờ/thông báo. This example cho thấy cách:

#include <iostream> 
#include <string> 
#include <thread> 
#include <mutex> 
#include <condition_variable> 

std::mutex m; 
std::condition_variable cv; 
std::string data; 
bool mainReady = false; 
bool workerReader = false; 

void worker_thread() 
{ 
    // Wait until main() sends data 
    { 
     std::unique_lock<std::mutex> lk(m); 
     cv.wait(lk, []{return mainReady;}); 
    } 

    std::cout << "Worker thread is processing data: " << data << std::endl; 
    data += " after processing"; 

    // Send data back to main() 
    { 
     std::lock_guard<std::mutex> lk(m); 
     workerReady = true; 
     std::cout << "Worker thread signals data processing completed\n"; 
    } 
    cv.notify_one(); 
} 

int main() 
{ 
    std::thread worker(worker_thread); 

    data = "Example data"; 
    // send data to the worker thread 
    { 
     std::lock_guard<std::mutex> lk(m); 
     mainReady = true; 
     std::cout << "main() signals data ready for processing\n"; 
    } 
    cv.notify_one(); 

    // wait for the worker 
    { 
     std::unique_lock<std::mutex> lk(m); 
     cv.wait(lk, []{return workerReady;}); 
    } 
    std::cout << "Back in main(), data = " << data << '\n'; 


    // wait until worker dies finishes execution 
    worker.join(); 
} 

Mã này cũng nhấn mạnh một số điểm mạnh khác mà C++ có hơn C:

  1. mã này không chứa một con trỏ nguyên đơn (which are treacherous)
  2. lambda expressions
  3. tất cả các loại khác syntactic swagg.
Các vấn đề liên quan