Pthreads 入门
首先,对于一个 Pthreads 并行程序来说,它的一般步骤为:
- 定义线程函数,每个线程的具体操作
- 创建线程
- 同步线程
- 销毁线程
基本API
pthread_create( ) 创建
pthread_t myThread;
pthread_create(&myThread, NULL, myThreadFunction, NULL);
pthread_t myThread
:用于存储新线程的标识符。pthread_create
函数的第一个参数是指向pthread_t
类型的指针,用于存储新线程的标识符。NULL
:线程的属性,通常设为NULL
表示使用默认属性。myThreadFunction
:要在新线程中执行的函数。NULL
:传递给线程函数的参数,如果没有参数可以设为NULL
。
pthread_mutex_lock( ) 同步
方法一:互斥锁(Mutex):
#include <pthread.h>
#include <stdio.h>
// 定义互斥锁
pthread_mutex_t myMutex = PTHREAD_MUTEX_INITIALIZER;
void* myThreadFunction(void* arg) {
// 锁定互斥锁
pthread_mutex_lock(&myMutex);
// 临界区代码,对共享资源的访问
printf("hello<dai_tu>");
// 解锁互斥锁
pthread_mutex_unlock(&myMutex);
return NULL;
}
int main() {
pthread_t myThread;
pthread_create(&myThread, NULL, myThreadFunction, NULL);
// 主线程也可以在这里进行一些操作
// 等待线程结束
pthread_join(myThread, NULL);
return 0;
}
方法二:条件变量(Condition Variable):
#include <pthread.h>
#include <stdio.h>
pthread_mutex_t myMutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t myCond = PTHREAD_COND_INITIALIZER;
int condition = 0;
void* myThreadFunction(void* arg) {
// 锁定互斥锁
pthread_mutex_lock(&myMutex);
// 检查条件
while (condition == 0) {
// 等待条件变量信号
pthread_cond_wait(&myCond, &myMutex);
}
// 条件满足后的代码
// 解锁互斥锁
pthread_mutex_unlock(&myMutex);
return NULL;
}
int main() {
pthread_t myThread;
pthread_create(&myThread, NULL, myThreadFunction, NULL);
// 在主线程中改变条件并通知等待的线程
pthread_mutex_lock(&myMutex);
condition = 1;
pthread_cond_signal(&myCond);
pthread_mutex_unlock(&myMutex);
// 等待线程结束
pthread_join(myThread, NULL);
return 0;
}
pthread_exit( )销毁线程
#include <pthread.h>
#include <stdio.h>
void* myThreadFunction(void* arg) {
// 线程执行的代码
pthread_exit((void*)42);
}
int main() {
pthread_t myThread;
pthread_create(&myThread, NULL, myThreadFunction, NULL);
// 等待线程结束并获取返回值
void* result;
pthread_join(myThread, &result);
printf("Thread returned: %ld\n", (long)result);
return 0;
}
下面是一个用梯形法求面积的代码:
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#define NUM_THREADS 4
#define N 1000000
double a = 0.0, b = 1.0;
int n = N;
double h;
double sum = 0.0;
pthread_mutex_t mutex;
sem_t semaphore;
void* trapezoidal_integration(void* arg) {
int thread_id = *((int*)arg);
double local_sum = 0.0;
for (int i = thread_id; i < n; i += NUM_THREADS) {
double x_i = a + i * h;
double x_i1 = a + (i + 1) * h;
local_sum += (f(x_i) + f(x_i1)) / 2.0 * h;
}
// 使用互斥锁更新总和
pthread_mutex_lock(&mutex);
sum += local_sum;
pthread_mutex_unlock(&mutex);
// 使用信号量通知主线程计算完成
sem_post(&semaphore);
pthread_exit(NULL);
}
int main() {
pthread_t threads[NUM_THREADS];
int thread_ids[NUM_THREADS];
h = (b - a) / n;
pthread_mutex_init(&mutex, NULL);
sem_init(&semaphore, 0, 0);
// 创建线程
for (int i = 0; i < NUM_THREADS; i++) {
thread_ids[i] = i;
pthread_create(&threads[i], NULL, trapezoidal_integration, (void*)&thread_ids[i]);
}
// 等待所有线程完成
for (int i = 0; i < NUM_THREADS; i++) {
sem_wait(&semaphore);
}
// 打印最终结果
printf("Result: %f\n", sum);
pthread_mutex_destroy(&mutex);
sem_destroy(&semaphore);
return 0;
}
该函数如下图:
验算一下, F(x) = (1/4)x^4 - x^3 + (3/2)x^2 - 10x , F(1)-F(0) = [ 0.25 - 1 + 1.5 - 10 ] - 0 = |-9.25| (比较接近了)
Pthreads比较简单,就没有做过多的笔记,下面是函数速记表:
-
pthread_create:
- 用于创建新的线程。
cCopy codeint pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
-
pthread_join:
- 用于等待一个线程的结束,并获取其返回值。
cCopy code int pthread_join(pthread_t thread, void **retval);
-
pthread_exit:
- 用于终止调用它的线程,并返回一个指针值。
cCopy code void pthread_exit(void *retval);
-
pthread_cancel:
- 用于请求取消指定线程。
cCopy code int pthread_cancel(pthread_t thread);
-
pthread_mutex_init:
- 用于初始化互斥锁。
cCopy code int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
-
pthread_mutex_lock / pthread_mutex_unlock:
- 用于锁定和解锁互斥锁。
cCopy codeint pthread_mutex_lock(pthread_mutex_t *mutex); int pthread_mutex_unlock(pthread_mutex_t *mutex);
-
pthread_cond_init:
- 用于初始化条件变量。
cCopy code int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);
-
pthread_cond_wait / pthread_cond_signal:
- 用于等待和发送条件变量信号。
cCopy codeint pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); int pthread_cond_signal(pthread_cond_t *cond);
-
pthread_rwlock_init / pthread_rwlock_rdlock / pthread_rwlock_wrlock / pthread_rwlock_unlock:
- 用于初始化、读锁、写锁和解锁读写锁。
cCopy codeint pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr); int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock); int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock); int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
-
pthread_barrier_init / pthread_barrier_wait:
- 用于初始化和等待屏障。
cCopy codeint pthread_barrier_init(pthread_barrier_t *barrier, const pthread_barrierattr_t *attr, unsigned count); int pthread_barrier_wait(pthread_barrier_t *barrier);
-
pthread_attr_init / pthread_attr_destroy:
- 用于初始化和销毁线程属性对象。
cCopy codeint pthread_attr_init(pthread_attr_t *attr); int pthread_attr_destroy(pthread_attr_t *attr);
read_barrierattr_t *attr, unsigned count);
int pthread_barrier_wait(pthread_barrier_t *barrier);
```
-
pthread_attr_init / pthread_attr_destroy:
- 用于初始化和销毁线程属性对象。
cCopy codeint pthread_attr_init(pthread_attr_t *attr); int pthread_attr_destroy(pthread_attr_t *attr);