原理:

作一个2×2正方形的内切圆,其圆心假设为(0,0)(如下图所示)且半径为1,生成一系列随机点(x,y)且这些点必须在正方形内,在所产生的所有随机点中,有一些点会出现在圆内,然后通过以下公式估算圆周率π的值:

π = 4×(圆内点总数)/(点的总数)

主要使用的头文件:

pthread.h头文件下的各类函数及变量:

//pthread.h头文件
#include<pthread.h>
//定义线程变量
typedef uintptr_t pthread_t;
//线程的创建
int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
//等待线程执行完成
int pthread_join(pthread_t thread, void **retval);
//定义互斥锁变量
typedef void *pthread_mutex_t;
//互斥锁的初始化
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
//或者使用以下宏定义直接赋值
#define PTHREAD_MUTEX_INITIALIZER (pthread_mutex_t)GENERIC_INITIALIZER
//申请互斥锁
int pthread_mutex_lock(pthread_mutex_t *m);
//释放互斥锁
int pthread_mutex_unlock(pthread_mutex_t *m)
//销毁互斥锁
int pthread_mutex_destroy(pthread_mutex_t *m);

time.h头文件下的各类函数及变量:

//time.h头文件
#include<time.h>
//用时间做种子使随机数随机化
void srand(unsigned int _Seed);
//随机函数
int rand(void);

主要部分:

每个线程执行的函数过程monte_carlo(),产生随机点并计算落在圆内的个数(经优化为计算落在四分之一圆内的随机点个数,每个线程平均分配计算次数):

void* monte_carlo(void* tid)                        //统计函数,每个子线程算200遍
{srand((unsigned)time(NULL));int i = 0;while(i<TOTAL_NUM/THREAD_NUM){pthread_mutex_lock(&lock);                  //申请互斥锁/*产生随机的x、y坐标值*/double pointX = (double)rand()/(double)RAND_MAX;double pointY = (double)rand()/(double)RAND_MAX;double l = pointX*pointX+pointY*pointY;/*判断是否位于圆内*/if(l<=1.0)++circle_num;++num;++i;pthread_mutex_unlock(&lock);                //释放互斥锁}}

主函数中线程的创建(使用了数组,可以不用数组或者增加线程个数,本程序中用了2个子线程):

pthread_t thread[THREAD_NUM];                   //线程定义int i, state;for(i = 0;i<THREAD_NUM;i++)                     //线程创建{printf("create thread%d\n", i);state = pthread_create(&thread[i], NULL, monte_carlo, NULL);if(state){printf("error!\n");exit(-1);}}

主函数中,父线程等待子线程完成再执行下一步语句:

for(i = 0;i<THREAD_NUM;i++)                     //等待子线程完成{pthread_join(thread[i],NULL);}

编译运行程序(Windows),结果如下:

跟圆周率相比误差约为小数点后5位,得出了圆周率的近似值。

附:程序代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<time.h>
#define TOTAL_NUM 10000000                          //设置点的总数
#define THREAD_NUM 2                                //线程总数pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;   //定义互斥锁
int circle_num = 0;                                 //统计圆内点数
int num = 0;                                       //计数用,防止程序出错void* monte_carlo(void* tid)                        //统计函数,每个子线程算200遍
{srand((unsigned)time(NULL));int i = 0;while(i<TOTAL_NUM/THREAD_NUM){pthread_mutex_lock(&lock);                  //申请互斥锁/*产生随机的x、y坐标值*/double pointX = (double)rand()/(double)RAND_MAX;double pointY = (double)rand()/(double)RAND_MAX;double l = pointX*pointX+pointY*pointY;/*判断是否位于圆内*/if(l<=1.0)++circle_num;++num;++i;pthread_mutex_unlock(&lock);                //释放互斥锁}}int main()
{pthread_t thread[THREAD_NUM];                   //线程定义int i, state;for(i = 0;i<THREAD_NUM;i++)                     //线程创建{printf("create thread%d\n", i);state = pthread_create(&thread[i], NULL, monte_carlo, NULL);if(state){printf("error!\n");exit(-1);}}for(i = 0;i<THREAD_NUM;i++)                     //等待子线程完成{pthread_join(thread[i],NULL);}pthread_mutex_destroy(&lock);                   //销毁互斥锁/*将pi的结果打印*/printf("num = %d, circle_num = %d, pi = %.5lf\n", num, circle_num, 4.0*circle_num/TOTAL_NUM);return 0;
}

多线程设计实例——Monte Carlo法估算圆周率相关推荐

  1. 连续反应matlab,MATLAB和Monte Carlo法在连续反应动力学中的应用.pdf

    第42卷第4期 广 州 化 工 Vo1.42No.4 2014年 2月 GuangzhouChemicalIndustry Feb.2014 MATLAB和 MonteCarlo法在连续反应动力学中的 ...

  2. 蒙特卡罗(Monte Carlo)方法计算圆周率π

    一.蒙特卡洛(Monte Carlo)方法简介 蒙特卡洛是一个地名,位于赌城摩纳哥,象征概率.蒙特卡洛(Monte Carlo)方法是由大名鼎鼎的数学家冯·诺伊曼提出的,诞生于上世纪40年代美国的&q ...

  3. linux多线程编程实现圆周率,linux环境下使用Monte Carlo计算π

    1 实验题目 计算π的一个有趣方法是使用一个称为Monte Carlo的技术,这种技术涉及随机.该技术工作如下:假设有一个圆,它内嵌一个正方形,如下图所示. 首先,通过(x,y)坐标生成一系列的随机点 ...

  4. 强化学习(四) - 蒙特卡洛方法(Monte Carlo Methods)及实例

    强化学习(四) - 蒙特卡洛方法(Monte Carlo Methods)及实例 4. 蒙特卡洛方法 4.1 蒙特卡洛预测 例4.1:Blackjack(21点) 4.2 动作价值的蒙特卡洛估计 4. ...

  5. 蒙特卡洛(Monte Carlo)法求定积分

    蒙特卡洛(Monte Carlo)法是一类随机算法的统称.随着二十世纪电子计算机的出现,蒙特卡洛法已经在诸多领域展现出了超强的能力.在机器学习和自然语言处理技术中,常常被用到的MCMC也是由此发展而来 ...

  6. ADPRL - 近似动态规划和强化学习 - Note 10 - 蒙特卡洛法和时序差分学习及其实例 (Monte Carlo and Temporal Difference)

    Note 10 蒙特卡洛法和时序差分学习 Monte Carlo and Temporal Difference 蒙特卡洛法和时序差分学习 Note 10 蒙特卡洛法和时序差分学习 Monte Car ...

  7. 蒙特卡罗(Monte Carlo)法

    蒙特卡罗(Monte Carlo)法 又称统计实验法,是以概率论和数理统计为指导的模拟方法. 它的实质是运用一连串的随机数来模拟可能出现的随机现象,即为了求解确定的数学问题,要构造一个与原来的问题没有 ...

  8. martingale、markov chain、Monte Carlo、MCMC

    文章结构如下: 1: MCMC 1.1 MCMC是什么 1.2 为什么需要MCMC 2: 蒙特卡罗 2.1 引入 2.2 均匀分布,Box-Muller 变换 2.3 拒绝接受采样(Acceptanc ...

  9. python计算圆周率_python模拟蒙特·卡罗法计算圆周率

    蒙特·卡罗方法是一种通过概率来得到问题近似解的方法,在很多领域都有重要的应用,其中就包括圆周率近似值的计问题. 假设有一块边长为2的正方形木板,上面画一个单位圆,然后随意往木板上扔飞镖,落点坐标(x, ...

  10. 蒙特卡罗方法(Monte Carlo method)浅入

    蒙特卡罗方法概述 蒙特卡罗方法又称统计模拟法.随机抽样技术,是一种随机模拟方法,以概率和统计理论方法为基础的一种计算方法,是使用随机数(或更常见的伪随机数)来解决很多计算问题的方法.将所求解的问题同一 ...

最新文章

  1. vs2008中常见错误解决方法汇总
  2. UCL葡萄酒(red white wine quality)数据集字段解释、数据导入实战
  3. fir.im Weekly - iOS 保持界面流畅的技巧 1
  4. php作品答辩问问题,一般答辩会问到什么问题
  5. 给Vista系统加入一键还原功能
  6. vue全选和取消全选(无bug)
  7. Linux扫描工具rootkit部署
  8. 第三节 UNIX文件系统结构
  9. vs2005的MSDN的下载
  10. 铺铜需要把agnd和dgnd分开_AGNDDGND 分析
  11. PPT图片虚化效果要怎样实现?
  12. AndroidStudio 集成 OpenCV
  13. 藏语计算机基础知识,2017年青海民族大学计算机学院738藏语与现代汉语基础考研题库...
  14. android系统定制教程,Android系统DIY修改 定制第三方ROM教程
  15. 盘点 Java 线程池配置的常见误区
  16. Microsoft Remote Procedure Call Runtime 远程代码执行漏洞(CVE-2022-26809)
  17. 五种常见启发式算法求解TSP问题-总结篇
  18. 利用计算机解决鸡兔同笼问题,Python解决鸡兔同笼问题的方法
  19. 【C语言】assert() 断言的作用
  20. 7-4 宿舍谁最高? (20 分) map+结构体的应用

热门文章

  1. windows编译opencv+opencv_contrib 以及解决cmake下载boostdesc_bgm等文件失败问题
  2. cmake下载,安装
  3. git使用puttygen生成公钥私钥
  4. 找出回文字符串用c语言写,寻找回文字符串
  5. 【Jlink驱动无法加载解决办法】
  6. IC卡防复制 设备联网 动态密钥方案说明 一卡通 门禁卡防破解Mifare卡低成本动态加密实现思路
  7. sata接口 图解 定义_SATA数据和电源接口定义详解
  8. 招聘笔试c语言题库,2014年腾讯校园招聘C语言笔试题含答案
  9. 杨辉三角数学性质及参考例题
  10. linux里画pcb软件有哪些,Linux系统用什么软件画pcb啊