2012-05-04 18 views
8

Tôi đang lập trình bằng C++, nhưng tôi chỉ sử dụng các chủ đề pthread.h, no boost hoặc C++ 11. Vì vậy, tôi đang cố gắng sử dụng các đề tài nhưng dựa trên một trong các câu hỏi trước đây của tôi (link), điều này dường như không khả thi vì các chủ đề chấm dứt ngay sau khi hoàn thành nhiệm vụ của nó và một trong những lý do phổ biến hơn để sử dụng một chuỗi- thực hiện nhóm là giảm chi phí tạo luồng bằng cách sử dụng lại các chủ đề này cho nhiều tác vụ.Hồ sơ luồng sẽ được triển khai như thế nào trong C?

Vì vậy, cách duy nhất khác để thực hiện điều này trong C là sử dụng fork() và tạo một đường ống từ quy trình chính đến con? Hoặc là có một cách để thiết lập một đường ống giữa chủ đề và cha mẹ của họ mà tôi không biết về?

Rất cám ơn trước!

+0

tạo thread Ẩn và có một danh sách các công việc (chức năng + object) với một số sự kiện đánh thức nên làm điều đó . Bạn đang tìm kiếm một số hành vi cụ thể? –

+2

Quyết định xem bạn có muốn giải pháp C hoặc C++ hay không. Cho dù thư viện cơ bản là pthreads (tức là C chỉ) là ít quan trọng hơn nhiều so với ngôn ngữ mà bạn muốn cung cấp các hồ bơi thread. –

+0

.. và sau đó chọn C++ –

Trả lời

6

Có, bạn có thể tạo thread-safe queue giữa các chuỗi. Sau đó, các chủ đề trong các hồ bơi sẽ ngồi trong một vòng lặp lấy một mục từ hàng đợi, thực hiện bất cứ điều gì nó cần, sau đó đi lại và nhận được một. Điều này thường dễ hơn một chút so với một số giao diện (ví dụ, quá tải operator() để thực thi mã cho một tác vụ), nhưng ở mức cơ bản, bạn có thể làm tất cả như nhau những thứ trong C (ví dụ, mỗi cấu trúc task bạn đưa vào hàng đợi sẽ chứa một con trỏ tới một hàm để thực hiện công việc cho nhiệm vụ đó).

Trong trường hợp của bạn, vì bạn đang sử dụng C++, có thể dễ dàng sử dụng quá tải operator() để thực hiện công việc. Phần còn lại của cấu trúc task (hoặc bất kỳ thứ gì bạn chọn gọi) sẽ chứa bất kỳ dữ liệu nào cần thiết, v.v.

+0

Vì vậy, lý tưởng, hàng đợi sẽ cần phải là chủ đề an toàn và sử dụng một semaphore với một val tối đa của số lượng tối đa của chủ đề mà tôi sẽ đẻ trứng, phải không? Việc triển khai này có vẻ hơi bẩn ... Tôi không bao giờ cảm thấy đúng khi đặt dữ liệu/vùng chứa "ở chế độ rõ ràng", không được đóng gói bởi một lớp học. Đó là lý do tại sao tôi hỏi về việc thực hiện đường ống master-child_thread –

+0

Chi phí của việc có một gói đóng gói dữ liệu cha mẹ-con_PROCESS có đáng giá không? –

+0

@ K-RAN: Người tôi liên kết (cuộn xuống "mã cuối cùng") * được * gói gọn trong một lớp học. –

3

Từ POSIX standard:

int pthread_create(pthread_t *restrict thread, 
    const pthread_attr_t *restrict attr, 
    void *(*start_routine)(void*), void *restrict arg); 

(...) Các chủ đề được tạo ra thực hiện start_routine với arg như là đối số duy nhất của nó.

Vì vậy, bạn nên tạo một loạt các chủ đề với chức năng này, và tất cả đều thực hiện một chức năng mà đi một cái gì đó giống như

void *consumer(void *arg) 
{ 
    WorkQueue *queue = static_cast<WorkQueue *>(arg); 

    for (task in queue) { 
     if (task == STOP_WORKING) 
      break; 
     do work; 
    } 
    return WHATEVER; 
} 

(Vào cuối đầu vào, đẩy nSTOP_WORKING mục vào hàng đợi nơi số n là số lượng chủ đề.)

Tâm trí bạn, pthread là API rất thấp cung cấp rất ít loại an toàn (tất cả dữ liệu được chuyển thành void p ointers). Nếu bạn đang cố gắng song song các tác vụ đòi hỏi nhiều CPU, bạn có thể muốn xem OpenMP để thay thế.

2

'dường như không khả thi vì các chủ đề chấm dứt ngay sau khi hoàn thành nhiệm vụ' what ??

for(;;){ 
    Task *myTask=theCommonProducerConsumerQueue->pop(); 
    myTask->run(); 
} 

.. không bao giờ trả lại bất kỳ thứ gì, trên thực tế, không bao giờ trả lại.

+0

Tôi chưa bao giờ nghĩ về điều đó trước khi đăng bài này, cũng như tôi không biết về phương pháp ngủ pthread; sự hiểu biết của tôi về các chủ đề trước đây là chúng là những thứ một-shot. –

-1

http://people.clarkson.edu/~jmatthew/cs644.archive/cs644.fa2001/proj/locksmith/code/ExampleTest/threadpool.c

tôi sử dụng google một vài tháng trước đây, bạn nên thử nó.

Chỉnh sửa: có vẻ như có thể bạn muốn nhóm thay thế. Tôi đã có thể tạo một cái với một số thay đổi nhỏ ở trên để công nhân không thực hiện công việc, nhưng chỉ cần tham gia các chủ đề.

+0

Bạn có bất kỳ ý tưởng làm thế nào để tích hợp này threadpool để thư viện sự kiện như libevent. Dường như có vòng lặp vô hạn riêng chờ đợi nhiệm vụ cho luồng. –

2

Bạn có thể thấy hữu ích khi xem the source code for libdispatch, là cơ sở cho Công văn Grand Central của Apple và sử dụng hồ bơi chuỗi.

+1

Whoa, thú vị. Cảm ơn! –

1

Tôi khuyên bạn nên sử dụng Threaded Building Blocks từ Intel để thực hiện các tác vụ như hàng đợi/công việc. Một ví dụ khá giả tạo sử dụng TBB 3.0:

class PoorExampleTask : public tbb::task { 
    PoorExampleTask(int foo, tbb::concurrent_queue<float>& results) 
    : _bar(foo), _results(results) 
    { } 

    tbb::task* execute() { 
     _results.push(pow(2.0, foo)); 
     return NULL; 
    } 

private: 
    int _bar; 
    tbb::concurrent_queue<float>& _results; 
} 

sử dụng sau này như sau:

tbb::concurrent_queue<float> powers; 
for (int ww = 0; ww < LotsOfWork; ++ww) { 
    PoorExampleTask* tt 
     = new (tbb::task::allocate_root()) PoorExampleTask(ww, powers); 
    tbb::task::enqueue(*tt); 
}