接下来我为你详细讲解如何在Windows下使用Dev-C++开发基于pthread.h的多线程程序实例。
准备工作
安装Dev-C++
在开始之前,我们首先需要安装Dev-C++,可以从官网 https://sourceforge.net/projects/orwelldevcpp/ 下载最新的Dev-C++安装包。
安装pthread库
接下来我们需要安装pthread库。在Windows下我们可以使用MinGW-w64工具包进行安装。
下载地址:https://sourceforge.net/projects/mingw-w64/
安装完成后在MinGW-w64的安装目录下的bin文件夹内找到mingw-w64.bat文件,双击打开。在命令行窗口输入以下命令安装pthread库:
mingw-w64-x86_64-posix-seh-gcc -v -E -x c - -mthreads < /dev/null 2>&1 | grep -q -F "_beginthreadex"
完成安装之后在C:\Program Files\mingw-w64下会出现两个子文件夹:mingw32和mingw64。如果是64位系统需要使用mingw64文件夹,如果是32位系统则需要使用mingw32文件夹。我们将使用的是mingw64文件夹下的库文件。在该目录下找到lib文件夹中的pthreadGC2.dll和libpthreadGC2.a两个文件,并将其拷贝到Dev-C++安装目录下的lib文件夹中。
配置编译器
打开Dev-C++,依次点击菜单栏上的Tools -> Compiler Options,在弹出的窗口中选择General选项卡,在"Programs"栏中选择"Executable Path",将其中的路径修改为MinGW-w64的bin目录,比如"C:\Program Files\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin"。
接着选择"Directories"选项卡,在"Include Directories"中添加pthread的头文件目录,这里我的路径是"C:\Program Files\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\x86_64-w64-mingw32\include"。
最后在"Linker"选项卡中,在"Libraries"栏中添加"pthread"库,这里我的路径是"C:\Dev-Cpp\lib\libpthreadGC2.a"。
第一个示例程序
功能说明
第一个示例程序是一个简单的并行计算,它创建10个线程,每个线程计算从1到100的和,最终把所有线程计算结果加起来输出。
代码示例
#include <stdio.h>
#include <pthread.h>
#define THREAD_COUNT 10 // 线程数量
#define PER_THREAD_COUNT 10 // 每个线程计算的次数
void *thread_func(void *argp)
{
int *ret_value = (int *)malloc(sizeof(int));
*ret_value = 0;
int index = *(int *)argp;
int start = PER_THREAD_COUNT * index + 1;
int end = PER_THREAD_COUNT * (index + 1);
for (int i = start; i <= end; i++)
{
*ret_value += i;
}
return (void *)ret_value;
}
int main(int argc, char *argv[])
{
int sum = 0;
pthread_t threads[THREAD_COUNT];
void *retvals[THREAD_COUNT];
for (int i = 0; i < THREAD_COUNT; i++)
{
int *argp = (int *)malloc(sizeof(int));
*argp = i;
pthread_create(&threads[i], NULL, thread_func, (void *)argp);
}
for (int i = 0; i < THREAD_COUNT; i++)
{
pthread_join(threads[i], &retvals[i]);
sum += *(int *)retvals[i];
free(retvals[i]);
}
printf("Sum is %d\n", sum);
return 0;
}
代码说明
代码中创建了一个thread_func函数作为线程执行函数,在函数中传入计算的起始值和终止值参数,计算从起始值到终止值的和,并将其存储在堆上分配的内存中,最后返回这个内存地址。在主函数中利用pthread_create创建多个线程,利用pthread_join等待线程结束,最终将所有线程计算值的和输出。
第二个示例程序
功能说明
第二个示例程序是一个简单的生产者-消费者模型,它利用条件变量和互斥锁来实现生产和消费的同步。
代码示例
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#define BUFFER_SIZE 10
int buffer[BUFFER_SIZE]; // 缓冲区
int current_pos = 0; // 当前缓冲区位置
int product_num = 0; // 待生产产品数量
int consume_num = 0; // 已消费产品数量
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // 互斥锁
pthread_cond_t produce_cond = PTHREAD_COND_INITIALIZER; // 生产者条件变量
pthread_cond_t consume_cond = PTHREAD_COND_INITIALIZER; // 消费者条件变量
// 生产者线程
void *producer_thread(void *param)
{
while (product_num >= 0)
{
pthread_mutex_lock(&mutex);
while (current_pos == BUFFER_SIZE)
{
// 等待消费者消费
pthread_cond_wait(&consume_cond, &mutex);
}
buffer[current_pos] = product_num;
printf("Producer[%d] puts %d at position %d\n", pthread_self(), product_num, current_pos);
current_pos++;
product_num++;
pthread_cond_signal(&produce_cond); // 唤醒消费者
pthread_mutex_unlock(&mutex);
sleep(1);
}
return NULL;
}
// 消费者线程
void *consumer_thread(void *param)
{
while (consume_num < product_num)
{
pthread_mutex_lock(&mutex);
while (current_pos == 0)
{
// 等待生产者生产
pthread_cond_wait(&produce_cond, &mutex);
}
int value = buffer[current_pos - 1];
printf("Consumer[%d] gets %d from position %d\n", pthread_self(), value, current_pos - 1);
current_pos--;
consume_num++;
pthread_cond_signal(&consume_cond); // 唤醒生产者
pthread_mutex_unlock(&mutex);
sleep(1);
}
return NULL;
}
int main(int argc, char **argv)
{
pthread_t producer_tid, consumer_tid;
// 创建生产者线程和消费者线程
pthread_create(&producer_tid, NULL, producer_thread, NULL);
pthread_create(&consumer_tid, NULL, consumer_thread, NULL);
// 等待生产者和消费者线程结束
pthread_join(producer_tid, NULL);
pthread_join(consumer_tid, NULL);
printf("All done!\n");
return 0;
}
代码说明
代码中创建了一个生产者线程和一个消费者线程,生产者线程每秒生产一个产品并将其存入缓冲区中,消费者线程每秒取出一个产品并将其从缓冲区中移除。在开始时,product_num的值为0,代表生产者需要生产的产品数量;consume_num的值为0,代表消费者已经消费的产品数量。缓冲区的大小为10。
当生产者线程生产完一个产品后,将其放入缓冲区中,并将current_pos加1。如果缓冲区已满,则生产者线程进入等待状态,等待消费者线程消费完一个产品后唤醒。当消费者线程取出一个产品后,将其从缓冲区中移除,并将current_pos减1。如果缓冲区为空,则消费者线程进入等待状态,等待生产者线程生产一个新产品后唤醒。
需要注意的是,在访问缓冲区时需要加锁(mutex),以保证每个线程访问缓冲区的唯一性;在等待条件变量时需要解锁(mutex),以便其他线程可以访问和修改缓冲区的元素。在某个线程修改缓冲区的元素时,该线程需要修改current_pos的值,并将mutex解锁,以使其他线程能够访问缓冲区的元素。在线程执行完毕之后,需要调用pthread_join等待线程结束,并释放线程的资源。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Windows下使用Dev-C++开发基于pthread.h的多线程程序实例 - Python技术站