Pthreads程序实现任务队列

主线程启动用户指定数量的线程,这些线程进入条件等待状态。
主线程生成一些任务(一定计算量),每生成一个新的任务,就用条件变量唤醒一个线程,当这个唤醒线程执行完任务时,回到条件等待状态。
当主线程生成完所有任务,设置全局变量表示再没有要生成的任务了,并用一个广播唤醒所有线程。为了清晰起见,建议任务采用链表操作。

#include 
#include 
#include 
using namespace std;
const int N=1e4,N1=1e6;
struct Node {
    int id;
    int a[N1],b[N1];
    Node* next;
};
struct Queue {
    Node* front;
    Node* tail;
};
int InitQueue(Queue* T);
int Add(Queue* T, int e);
int DoTask(Queue* T, int* ep);
int thread_count, finished = 0;
pthread_mutex_t mutex,actprint;
pthread_cond_t cond;
void* task(void* rank);
Queue Q;
int main(int argc, char* argv[])
{   
    srand(0);
    InitQueue(&Q);
    pthread_t *thread_handles;
    thread_count = strtol(argv[1], NULL, 10);//从命令行读取线程数
    thread_handles = new pthread_t[thread_count];//分配长度

    pthread_mutex_init(&mutex, NULL);
    pthread_mutex_init(&actprint, NULL);
    pthread_cond_init(&cond, NULL);

    int n;
    printf("Please input the task number:");
    cin>>n;

    for (int i = 0; i < thread_count; i++)
        pthread_create(&thread_handles[i], NULL, task, (void*)i);

    for (int i = 0; i < n; i++) {
        pthread_mutex_lock(&mutex);
        Add(&Q, i);
        pthread_cond_signal(&cond);
        pthread_mutex_unlock(&mutex);
    }
    finished = 1;
    pthread_cond_broadcast(&cond);
    for (int i = 0; i < thread_count; i++)
        pthread_join(thread_handles[i], NULL);
    pthread_mutex_destroy(&mutex);
    pthread_mutex_destroy(&actprint);
    pthread_cond_destroy(&cond);
    free(thread_handles);
    return 0;
}
int InitQueue(Queue* T) {
    T->front = (Node*)malloc(sizeof(Node));
    T->tail = T->front;
    T->front->id = 0;
    T->front->next = NULL;
    return 0;
}
int Add(Queue* T, int e) {
    Node* newnode = (Node*)malloc(sizeof(Node));
    newnode->id = e;
    newnode->next = 0;
    int t,k=0;
    for(int i=0;i<N1;i++){
        t=rand()%N;
        newnode->a[k++]=t;
    }
    k=0;
    for(int i=0;i<N;i++){
        t=rand()%N;
        newnode->b[k++]=t;
    }
    T->tail->next = newnode;
    T->tail = newnode;
    return 0;
}
int DoTask(Queue* T, int* e) {
    Node* dest;
    if (T->tail == T->front)return 0;//队列中已经没有任务
    dest = T->front->next;//从头取出一个任务
    if (dest == 0) return 0;
    for(int i=0;i<N1;i++){//做任务
        dest->a[i]=dest->a[i]*dest->b[i];
    }
    *e = dest->id;
    T->front->next = dest->next;
    free(dest);
    return 0;
}
void* task(void* rank) {
    long long my_rank = (long long)rank;
    pthread_mutex_lock(&actprint);
    cout<<"process "<<my_rank<<" has been activated"<<endl;
    pthread_mutex_unlock(&actprint);
    int my_task;
    Node** p = &(Q.front->next);
    while (1) {
       pthread_mutex_lock(&mutex);
        if (finished) {
            if (*p == NULL) {
                pthread_mutex_unlock(&mutex);
                break;
            }
            DoTask(&Q, &my_task);
            pthread_mutex_unlock(&mutex);
            printf("Thread %ld: Task no.%d\n", my_rank, my_task);
        }else {
            while(pthread_cond_wait(&cond, &mutex)!=0);
            DoTask(&Q, &my_task);
            pthread_mutex_unlock(&mutex);
            printf("Thread %ld: Task no.%d\n", my_rank, my_task);
        }
    }
}

参考资料
Pthreads实现任务队列

你可能感兴趣的:(并行程序设计,并行程序设计,pthreads)