线程池计算素数:编写一个程序primer_thr3.c,程序运行开始时,创建10个子线程和一个包含20个元素的队列,主线程不断地依次将30000000到30000200之间这200个数放入队列,如果队列满,则主线程等待,代码需打印记录每次运行的时间
时间: 2023-12-04 20:04:42 浏览: 100
下面是实现该程序的代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/time.h>
#define MAX_QUEUE_SIZE 20
#define MAX_THREAD_NUM 10
int queue[MAX_QUEUE_SIZE];
int front = 0, rear = -1, count = 0, number = 30000000;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t queue_full = PTHREAD_COND_INITIALIZER;
pthread_cond_t queue_empty = PTHREAD_COND_INITIALIZER;
void *worker(void *arg) {
int id = *(int *)arg;
while (1) {
pthread_mutex_lock(&mutex);
while (count == 0) {
pthread_cond_wait(&queue_empty, &mutex);
}
int n = queue[front++];
front %= MAX_QUEUE_SIZE;
count--;
pthread_cond_signal(&queue_full);
pthread_mutex_unlock(&mutex);
int is_prime = 1;
for (int i = 2; i < n; i++) {
if (n % i == 0) {
is_prime = 0;
break;
}
}
if (is_prime) {
printf("[Thread %d] %d is a prime number\n", id, n);
}
}
return NULL;
}
int main() {
pthread_t threads[MAX_THREAD_NUM];
int thread_args[MAX_THREAD_NUM];
struct timeval start_time, end_time;
gettimeofday(&start_time, NULL);
for (int i = 0; i < MAX_THREAD_NUM; i++) {
thread_args[i] = i + 1;
pthread_create(&threads[i], NULL, worker, &thread_args[i]);
}
while (number <= 30000200) {
pthread_mutex_lock(&mutex);
while (count == MAX_QUEUE_SIZE) {
pthread_cond_wait(&queue_full, &mutex);
}
rear++;
rear %= MAX_QUEUE_SIZE;
queue[rear] = number++;
count++;
pthread_cond_signal(&queue_empty);
pthread_mutex_unlock(&mutex);
}
for (int i = 0; i < MAX_THREAD_NUM; i++) {
pthread_cancel(threads[i]);
}
gettimeofday(&end_time, NULL);
printf("Total time: %ld us\n", (end_time.tv_sec - start_time.tv_sec) * 1000000 + (end_time.tv_usec - start_time.tv_usec));
return 0;
}
```
程序的思路是这样的:
1. 主线程创建10个子线程,每个子线程都是一个无限循环的线程,从队列中取出整数并判断是否是素数。
2. 主线程循环将30000000到30000200之间的200个数放入队列中。
3. 如果队列已满,主线程等待队列不满时才继续放数。
4. 如果队列已空,子线程等待队列不空时才继续取数。
5. 子线程判断整数是否是素数,如果是素数则打印输出。
6. 主线程在子线程完成任务后,将子线程全部取消,然后输出程序的运行时间。
需要注意的是,主线程和子线程之间要加锁和条件变量控制队列的访问,否则可能会出现竞争条件,导致程序出错。同时,子线程也要注意使用pthread_cancel函数在主线程取消时及时退出,否则可能会导致程序无法正常结束。
阅读全文