2011-06-24 40 views
11

Trong đoạn mã sau đây tôi tạo ra một số chủ đề, và mỗi chủ đề ngủ trong một vài giây.làm cho chương trình chính chờ đợi cho các chủ đề để kết thúc

Tuy nhiên chương trình chính của tôi không đợi cho các chủ đề kết thúc, tôi đã được giả định rằng các chủ đề sẽ tiếp tục chạy cho đến khi chúng tự hoàn thành.

Có cách nào đó việc tạo chuỗi tiếp tục chạy ngay cả khi chuỗi cuộc gọi kết thúc.

#include <pthread.h> 
#include <iostream> 
#include <cstdio> 
#include <cstdlib> 


int sample(int min,int max){ 
    int r=rand(); 
    return (r %max+min); 
} 



void *worker(void *p){ 
    long i = (long) p; 
    int s = sample(1,10); 
    fprintf(stdout,"\tid:%ld will sleep: %d \n",i,s); 
    sleep(s); 
    fprintf(stdout,"\tid:%ld done sleeping \n",i,s); 
} 

pthread_t thread1; 

int main(){ 
    int nThreads = sample(1,10); 

    for(int i=0;i<nThreads;i++){ 
    fprintf(stderr,"\t-> Creating: %d of %d\n",i,nThreads); 
    int iret1 = pthread_create(&thread1, NULL, worker, (void*) i); 
    pthread_detach(thread1); 
    } 
    // sleep(10);//work if this is not commented out. 
    return 0; 
} 

Cảm ơn

Edit:

Xin lỗi vì không làm rõ, là nó có thể không giữ một cách rõ ràng theo dõi các chủ đề hoạt động hiện tại của tôi và bằng cách sử dụng tham gia.

+0

Nếu đây là một giao diện người dùng đồ họa, vâng điều này cũng đúng vì có một vòng lặp tin nhắn. Bạn phải có một điều kiện để tiếp tục chạy cho đến khi tất cả các luồng được hoàn thành chẳng hạn như tham gia. –

Trả lời

3

Mỗi chương trình có một chuỗi chính. Đây là luồng mà hàm main() của bạn thực thi. Khi việc thực thi chuỗi đó kết thúc, chương trình sẽ kết thúc cùng với tất cả các chủ đề của nó. Nếu bạn muốn chủ đề chính của bạn chờ các chủ đề khác, sử dụng phải sử dụng pthread_join chức năng

+0

Khi thực hiện xong chuỗi chính, ít nhất trong Linux chương trình/quá trình không chấm dứt, thay vào đó nó chạy như một zombie cho đến khi các luồng khác kết thúc và sau đó chương trình/quá trình cũng kết thúc. Để kiểm tra điều này, mã một luồng chỉ ngủ trong N giây, sau đó từ chủ đề chính tạo ra luồng và sau đó phát hành pthread_exit (0) từ luồng chính và xem quá trình còn sống nhưng ở trạng thái zombie và sau đó sau N giây kết thúc luồng điều này cũng làm cho chương trình/quá trình kết thúc. – user1656730

2

Bạn cần phải theo dõi các chủ đề. Bạn không làm điều đó bởi vì bạn đang sử dụng cùng một biến số thread1 cho mọi chuỗi bạn đang tạo.

Bạn theo dõi các chuỗi bằng cách tạo danh sách (hoặc mảng) của pthread_t các loại mà bạn chuyển đến hàm pthread_create(). Sau đó, bạn pthread_join() các chủ đề đó trong danh sách.

chỉnh sửa:

Vâng, thật sự rất lười khi bạn không theo dõi các chuỗi đang chạy. Tuy nhiên, bạn có thể thực hiện những gì bạn muốn bằng cách có một var toàn cục (được bảo vệ bởi một mutex) được tăng lên ngay trước khi một luồng kết thúc. Sau đó, trong chủ đề chính bạn có thể kiểm tra xem var đó có đến giá trị bạn muốn hay không. Nói nThreads trong mã mẫu của bạn.

+0

Nếu bạn sử dụng giải pháp thứ hai, đừng quên rằng tất cả các truy cập vào biến phải được đồng bộ hóa. –

2

Bạn cần phải tham gia mỗi chủ đề bạn tạo ra:

int main() 
{ 
    int     nThreads = sample(1,10); 
    std::vector<pthread_t> threads(nThreads); 

    for(i=0; i<nThreads; i++) 
    { 
      pthread_create(&threads[i], NULL, worker, (void*) i) 
    } 

    /* Wait on the other threads */ 
    for(i=0; i<nThreads; i++) 
    { 
      status* status; 
      pthread_join(threads[i], &status); 
    } 
} 
1

Bạn học được giả định của bạn là sai. Chính là đặc biệt. Thoát chính sẽ giết chủ đề của bạn. Vì vậy, có hai tùy chọn:

  1. Sử dụng pthread_exit để thoát khỏi chính. Chức năng này sẽ cho phép bạn thoát khỏi chính nhưng giữ cho các luồng khác chạy.

  2. Làm điều gì đó để giữ cho cuộc sống chính. Điều này có thể là bất cứ điều gì từ một vòng lặp (ngu ngốc và không hiệu quả) cho bất kỳ cuộc gọi chặn. pthread_join là phổ biến vì nó sẽ chặn nhưng cũng cung cấp cho bạn tình trạng trả về của các chủ đề, nếu bạn quan tâm, và làm sạch các tài nguyên thread chết. Nhưng với mục đích giữ chính từ chấm dứt bất kỳ cuộc gọi chặn nào sẽ thực hiện, ví dụ: lựa chọn, đọc một đường ống, khối trên một semaphore vv

Kể từ khi Martin cho thấy join(), đây là pthread_exit():

int main(){ 
    int nThreads = sample(1,10); 

    for(int i=0;i<nThreads;i++){ 
    fprintf(stderr,"\t-> Creating: %d of %d\n",i,nThreads); 
    int iret1 = pthread_create(&thread1, NULL, worker, (void*) i); 
    pthread_detach(thread1); 
    } 

    pthread_exit(NULL); 
} 
Các vấn đề liên quan