解释 pthread_create(&(pool->threads[i]), NULL, thread_func, (void *)pool);
时间: 2023-09-06 10:12:47 浏览: 43
pthread_create() 是一个函数,用于在 POSIX 环境下创建一个新的线程。它的原型如下:
```c
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
```
其中,参数 thread 是指向线程标识符的指针;参数 attr 是指向线程属性的指针;start_routine 是线程启动时要执行的函数;参数 arg 是传递给 start_routine 函数的参数。
调用 pthread_create() 函数后,它将创建一个新的线程,并将线程 ID 存储在 thread 指向的位置。线程将从 start_routine 函数开始执行,并使用 arg 指向的参数。如果成功创建线程,pthread_create() 将返回 0,否则返回一个非零的错误代码。
相关问题
pthread线程池实现快速排序并计时 c++
好的,这是一个比较复杂的问题,需要分步骤来回答。
首先,我们需要实现一个基本的快速排序算法,可以用以下的代码实现:
```c
void quick_sort(int *arr, int left, int right){
int i, j, pivot, temp;
if(left < right){
i = left;
j = right;
pivot = arr[left];
while(i < j){
while(i < j && arr[j] >= pivot)
j--;
if(i < j)
arr[i++] = arr[j];
while(i < j && arr[i] < pivot)
i++;
if(i < j)
arr[j--] = arr[i];
}
arr[i] = pivot;
quick_sort(arr, left, i - 1);
quick_sort(arr, i + 1, right);
}
}
```
接下来,我们需要实现一个线程池。这里我们使用pthread库实现。以下是线程池的代码:
```c
typedef struct{
int *arr;
int left;
int right;
} Task;
typedef struct{
Task *task_queue;
int queue_head;
int queue_tail;
int queue_size;
pthread_mutex_t queue_lock;
pthread_cond_t queue_not_empty;
pthread_cond_t queue_not_full;
pthread_t *threads;
int thread_count;
int is_shutdown;
} ThreadPool;
void thread_pool_init(ThreadPool *pool, int thread_count, int queue_size){
pool->thread_count = thread_count;
pool->queue_size = queue_size;
pool->queue_head = pool->queue_tail = 0;
pool->is_shutdown = 0;
pool->threads = (pthread_t *)malloc(sizeof(pthread_t) * thread_count);
pool->task_queue = (Task *)malloc(sizeof(Task) * queue_size);
pthread_mutex_init(&(pool->queue_lock), NULL);
pthread_cond_init(&(pool->queue_not_empty), NULL);
pthread_cond_init(&(pool->queue_not_full), NULL);
for(int i = 0; i < thread_count; i++)
pthread_create(&(pool->threads[i]), NULL, thread_func, (void *)pool);
}
void thread_pool_add_task(ThreadPool *pool, Task task){
pthread_mutex_lock(&(pool->queue_lock));
while((pool->queue_tail + 1) % pool->queue_size == pool->queue_head){
pthread_cond_wait(&(pool->queue_not_full), &(pool->queue_lock));
}
pool->task_queue[pool->queue_tail] = task;
pool->queue_tail = (pool->queue_tail + 1) % pool->queue_size;
pthread_cond_signal(&(pool->queue_not_empty));
pthread_mutex_unlock(&(pool->queue_lock));
}
void thread_pool_shutdown(ThreadPool *pool){
pthread_mutex_lock(&(pool->queue_lock));
pool->is_shutdown = 1;
pthread_cond_broadcast(&(pool->queue_not_empty));
pthread_mutex_unlock(&(pool->queue_lock));
for(int i = 0; i < pool->thread_count; i++)
pthread_join(pool->threads[i], NULL);
free(pool->threads);
free(pool->task_queue);
pthread_mutex_destroy(&(pool->queue_lock));
pthread_cond_destroy(&(pool->queue_not_empty));
pthread_cond_destroy(&(pool->queue_not_full));
}
void *thread_func(void *arg){
ThreadPool *pool = (ThreadPool *)arg;
Task task;
while(1){
pthread_mutex_lock(&(pool->queue_lock));
while(pool->queue_head == pool->queue_tail && !pool->is_shutdown){
pthread_cond_wait(&(pool->queue_not_empty), &(pool->queue_lock));
}
if(pool->is_shutdown){
pthread_mutex_unlock(&(pool->queue_lock));
pthread_exit(NULL);
}
task = pool->task_queue[pool->queue_head];
pool->queue_head = (pool->queue_head + 1) % pool->queue_size;
pthread_cond_signal(&(pool->queue_not_full));
pthread_mutex_unlock(&(pool->queue_lock));
quick_sort(task.arr, task.left, task.right);
}
}
```
最后,我们需要实现计时功能。可以用以下代码实现:
```c
#include <sys/time.h>
double get_time(){
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec + tv.tv_usec / 1000000.0;
}
```
现在我们需要将这些代码组合起来,实现一个快速排序的线程池,并计时。以下是完整的代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/time.h>
typedef struct{
int *arr;
int left;
int right;
} Task;
typedef struct{
Task *task_queue;
int queue_head;
int queue_tail;
int queue_size;
pthread_mutex_t queue_lock;
pthread_cond_t queue_not_empty;
pthread_cond_t queue_not_full;
pthread_t *threads;
int thread_count;
int is_shutdown;
} ThreadPool;
void quick_sort(int *arr, int left, int right){
int i, j, pivot, temp;
if(left < right){
i = left;
j = right;
pivot = arr[left];
while(i < j){
while(i < j && arr[j] >= pivot)
j--;
if(i < j)
arr[i++] = arr[j];
while(i < j && arr[i] < pivot)
i++;
if(i < j)
arr[j--] = arr[i];
}
arr[i] = pivot;
quick_sort(arr, left, i - 1);
quick_sort(arr, i + 1, right);
}
}
void thread_pool_init(ThreadPool *pool, int thread_count, int queue_size){
pool->thread_count = thread_count;
pool->queue_size = queue_size;
pool->queue_head = pool->queue_tail = 0;
pool->is_shutdown = 0;
pool->threads = (pthread_t *)malloc(sizeof(pthread_t) * thread_count);
pool->task_queue = (Task *)malloc(sizeof(Task) * queue_size);
pthread_mutex_init(&(pool->queue_lock), NULL);
pthread_cond_init(&(pool->queue_not_empty), NULL);
pthread_cond_init(&(pool->queue_not_full), NULL);
for(int i = 0; i < thread_count; i++)
pthread_create(&(pool->threads[i]), NULL, thread_func, (void *)pool);
}
void thread_pool_add_task(ThreadPool *pool, Task task){
pthread_mutex_lock(&(pool->queue_lock));
while((pool->queue_tail + 1) % pool->queue_size == pool->queue_head){
pthread_cond_wait(&(pool->queue_not_full), &(pool->queue_lock));
}
pool->task_queue[pool->queue_tail] = task;
pool->queue_tail = (pool->queue_tail + 1) % pool->queue_size;
pthread_cond_signal(&(pool->queue_not_empty));
pthread_mutex_unlock(&(pool->queue_lock));
}
void thread_pool_shutdown(ThreadPool *pool){
pthread_mutex_lock(&(pool->queue_lock));
pool->is_shutdown = 1;
pthread_cond_broadcast(&(pool->queue_not_empty));
pthread_mutex_unlock(&(pool->queue_lock));
for(int i = 0; i < pool->thread_count; i++)
pthread_join(pool->threads[i], NULL);
free(pool->threads);
free(pool->task_queue);
pthread_mutex_destroy(&(pool->queue_lock));
pthread_cond_destroy(&(pool->queue_not_empty));
pthread_cond_destroy(&(pool->queue_not_full));
}
void *thread_func(void *arg){
ThreadPool *pool = (ThreadPool *)arg;
Task task;
while(1){
pthread_mutex_lock(&(pool->queue_lock));
while(pool->queue_head == pool->queue_tail && !pool->is_shutdown){
pthread_cond_wait(&(pool->queue_not_empty), &(pool->queue_lock));
}
if(pool->is_shutdown){
pthread_mutex_unlock(&(pool->queue_lock));
pthread_exit(NULL);
}
task = pool->task_queue[pool->queue_head];
pool->queue_head = (pool->queue_head + 1) % pool->queue_size;
pthread_cond_signal(&(pool->queue_not_full));
pthread_mutex_unlock(&(pool->queue_lock));
quick_sort(task.arr, task.left, task.right);
}
}
double get_time(){
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec + tv.tv_usec / 1000000.0;
}
int main(){
int arr[1000000];
for(int i = 0; i < 1000000; i++)
arr[i] = rand() % 1000000;
ThreadPool pool;
thread_pool_init(&pool, 4, 10000);
double start_time = get_time();
Task task;
task.arr = arr;
task.left = 0;
task.right = 999999;
thread_pool_add_task(&pool, task);
thread_pool_shutdown(&pool);
double end_time = get_time();
printf("Time: %lf\n", end_time - start_time);
return 0;
}
```
运行程序,可以看到输出的时间,就是快速排序的时间。注意,线程池的线程数和任务队列大小可以根据自己的需求进行调整。
线程池计算素数:编写一个程序primer_thr3.c,程序运行开始时,创建10个子线程和一个包含20个元素的队列,主线程不断地依次将30000000到30000200之间这200个数放入队列,如果队列满,则主线程等待。
以下是完整的primer_thr3.c程序代码,实现了线程池计算素数的功能:
```c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define QUEUE_SIZE 20
#define THREAD_COUNT 10
typedef struct {
int num;
int is_prime;
} task_t;
int start = 30000000;
int end = 30000200;
int *results;
pthread_mutex_t result_lock = PTHREAD_MUTEX_INITIALIZER;
typedef struct {
task_t *tasks;
int capacity;
int front;
int rear;
pthread_mutex_t lock;
pthread_cond_t not_empty;
pthread_cond_t not_full;
pthread_t *threads;
int thread_count;
int stop;
} thread_pool_t;
void init_thread_pool(thread_pool_t *pool, int capacity, int thread_count);
void *thread_func(void *arg);
int is_prime(int num);
int main() {
results = malloc((end - start + 1) * sizeof(int));
thread_pool_t pool;
init_thread_pool(&pool, QUEUE_SIZE, THREAD_COUNT);
for (int i = start; i <= end; i++) {
task_t task = {i, 0};
pthread_mutex_lock(&pool.lock);
while ((pool.rear + 1) % pool.capacity == pool.front) {
pthread_cond_wait(&pool.not_full, &pool.lock);
}
pool.tasks[pool.rear] = task;
pool.rear = (pool.rear + 1) % pool.capacity;
pthread_cond_signal(&pool.not_empty);
pthread_mutex_unlock(&pool.lock);
}
while (1) {
pthread_mutex_lock(&pool.lock);
if (pool.front == pool.rear) {
pthread_mutex_unlock(&pool.lock);
break;
}
pthread_mutex_unlock(&pool.lock);
}
pool.stop = 1;
pthread_cond_broadcast(&pool.not_empty);
for (int i = 0; i < pool.thread_count; i++) {
pthread_join(pool.threads[i], NULL);
}
pthread_mutex_destroy(&pool.lock);
pthread_cond_destroy(&pool.not_empty);
pthread_cond_destroy(&pool.not_full);
free(pool.tasks);
free(pool.threads);
for (int i = start; i <= end; i++) {
printf("%d %s\n", i, results[i - start] ? "is prime" : "is not prime");
}
free(results);
return 0;
}
void init_thread_pool(thread_pool_t *pool, int capacity, int thread_count) {
pool->tasks = malloc(capacity * sizeof(task_t));
pool->capacity = capacity;
pool->front = 0;
pool->rear = 0;
pthread_mutex_init(&pool->lock, NULL);
pthread_cond_init(&pool->not_empty, NULL);
pthread_cond_init(&pool->not_full, NULL);
pool->threads = malloc(thread_count * sizeof(pthread_t));
pool->thread_count = thread_count;
pool->stop = 0;
for (int i = 0; i < thread_count; i++) {
pthread_create(&pool->threads[i], NULL, thread_func, pool);
}
}
void *thread_func(void *arg) {
thread_pool_t *pool = (thread_pool_t *) arg;
while (1) {
pthread_mutex_lock(&pool->lock);
while (pool->front == pool->rear && !pool->stop) {
pthread_cond_wait(&pool->not_empty, &pool->lock);
}
if (pool->stop) {
pthread_mutex_unlock(&pool->lock);
pthread_exit(NULL);
}
task_t task = pool->tasks[pool->front];
pool->front = (pool->front + 1) % pool->capacity;
pthread_cond_signal(&pool->not_full);
pthread_mutex_unlock(&pool->lock);
task.is_prime = is_prime(task.num);
pthread_mutex_lock(&result_lock);
results[task.num - start] = task.is_prime;
pthread_mutex_unlock(&result_lock);
}
return NULL;
}
int is_prime(int num) {
if (num < 2) {
return 0;
}
for (int i = 2; i * i <= num; i++) {
if (num % i == 0) {
return 0;
}
}
return 1;
}
```
程序首先定义了一个任务结构体task_t,其中包含一个待计算的数值num和一个标志位is_prime,表示该数值是否为素数。然后定义了一个线程池结构体thread_pool_t,包含一个任务队列和一定数量的线程。线程池的初始化函数init_thread_pool中包括创建任务队列、初始化线程和启动线程等步骤。
主函数main中循环向任务队列中添加任务,并通过线程池的线程函数thread_func计算素数并回传计算结果。最后等待所有任务完成后销毁线程池,并通过results数组输出计算结果。
线程函数thread_func中取出任务、计算素数和回传结果等步骤,其中使用了互斥锁和条件变量保证了线程安全。计算素数的函数is_prime使用了较为简单的算法判断是否为素数。