proj.4 线程安全

本文翻译自proj.4开发者文档

原文链接 http://proj4.org/development/threads.html

线程安全关键问题

全局变量pj_error是在线程之间共享的,使得它基本上不可能安全的处理错误(译注:这个和C的errno不一样)。通过引进执行上下文projCtx来解决这个问题。

原点平移使用的网格文件,需要使用到全局共享的网格信息载入列表。proj 4.7.0版本中引入mutex(互斥锁)来保护这些存储结构(参见pj_mutex.c),在4.7.0及后续版本中对此访问是线程安全的。

projCtx

为了避免将pr_errno作为全局变量,4.8.0版本中将thread context(线程上下文)结构引入到PROJ.4 API中。pj_init()pj_init_plus()函数现在具有需要线程上下文变量的版本pj_init_ctx()pj_init_plus_ctx(),采用投影上下文(projections context)。

可以使用pj_ctx_alloc()创建投影上下文(projections context),当应用程序不提供投影上下文的时候,会使用全局默认上下文。有一系列pj_ctx_...的函数用于创建操作查询销毁上下文。上下文现在还可用来处理设置调试模式,并保持用于文本错误和调试消息的错误报告功能。API如下所示:

projPJ pj_init_ctx( projCtx, int, char ** );
projPJ pj_init_plus_ctx( projCtx, const char * ); projCtx pj_get_default_ctx(void);
projCtx pj_get_ctx( projPJ );
void pj_set_ctx( projPJ, projCtx );
projCtx pj_ctx_alloc(void);
void pj_ctx_free( projCtx );
int pj_ctx_get_errno( projCtx );
void pj_ctx_set_errno( projCtx, int );
void pj_ctx_set_debug( projCtx, int );
void pj_ctx_set_logger( projCtx, void (*)(void *, int, const char *) );
void pj_ctx_set_app_data( projCtx, void * );
void *pj_ctx_get_app_data( projCtx );

在多线程程序中应当使用pj_ctx_alloc()为每个线程创建projCtx。如果需要,上下文错误处理程序也许可以修改应用数据,但至少每个上下文都有一个内部错误值,使用pj_ctx_get_errno()访问,而不是查看pj_errno

注意,pj_errno依然存在,并且它由pj_ctx_set_errno()设置(以及设置上下文特定的错误数),但pj_errno仍然受到线程之间的全局共享问题的困扰,不应该被多线程应用程序使用。

注意 pj_init_ctx()pj_init_plus_ctx会将projCtx分配给创建的projPJ对象。像是pj_transform(),pj_fwd()pj_inv()等函数会对使用上下文的projPJ进行错误报告(会将错误信息报告到上下文)。

src/multistresstest.c

已经编写了一个小的多线程测试程序(src/multistresstest.c)用于测试PROJ.4的多线程使用。它执行一系列重投影来设置预期结果表,然后在多个线程中执行它们多次来确认结果是否一致。这个程序不会在构建proj4的时候构建,在类linux上可以使用如下命令构建:

gcc -g multistresstest.c .libs/libproj.so -lpthread -o multistresstest
./multistresstest

proj.4 线程安全的更多相关文章

  1. Disruptor——一种可替代有界队列完成并发线程间数据交换的高性能解决方案

    本文翻译自LMAX关于Disruptor的论文,同时加上一些自己的理解和标注.Disruptor是一个高效的线程间交换数据的基础组件,它使用栅栏(barrier)+序号(Sequencing)机制协调 ...

  2. [ 高并发]Java高并发编程系列第二篇--线程同步

    高并发,听起来高大上的一个词汇,在身处于互联网潮的社会大趋势下,高并发赋予了更多的传奇色彩.首先,我们可以看到很多招聘中,会提到有高并发项目者优先.高并发,意味着,你的前雇主,有很大的业务层面的需求, ...

  3. [高并发]Java高并发编程系列开山篇--线程实现

    Java是最早开始有并发的语言之一,再过去传统多任务的模式下,人们发现很难解决一些更为复杂的问题,这个时候我们就有了并发. 引用 多线程比多任务更加有挑战.多线程是在同一个程序内部并行执行,因此会对相 ...

  4. 多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类)

    前言:刚学习了一段机器学习,最近需要重构一个java项目,又赶过来看java.大多是线程代码,没办法,那时候总觉得多线程是个很难的部分很少用到,所以一直没下决定去啃,那些年留下的坑,总是得自己跳进去填 ...

  5. Java 线程

    线程:线程是进程的组成部分,一个进程可以拥有多个线程,而一个线程必须拥有一个父进程.线程可以拥有自己的堆栈,自己的程序计数器和自己的局部变量,但不能拥有系统资源.它与父进程的其他线程共享该进程的所有资 ...

  6. C++实现线程安全的单例模式

    在某些应用环境下面,一个类只允许有一个实例,这就是著名的单例模式.单例模式分为懒汉模式,跟饿汉模式两种. 首先给出饿汉模式的实现 template <class T> class sing ...

  7. 记一次tomcat线程创建异常调优:unable to create new native thread

    测试在进行一次性能测试的时候发现并发300个请求时出现了下面的异常: HTTP Status 500 - Handler processing failed; nested exception is ...

  8. Android线程管理之ThreadLocal理解及应用场景

    前言: 最近在学习总结Android的动画效果,当学到Android属性动画的时候大致看了下源代码,里面的AnimationHandler存取使用了ThreadLocal,激起了我很大的好奇心以及兴趣 ...

  9. C#多线程之线程池篇3

    在上一篇C#多线程之线程池篇2中,我们主要学习了线程池和并行度以及如何实现取消选项的相关知识.在这一篇中,我们主要学习如何使用等待句柄和超时.使用计时器和使用BackgroundWorker组件的相关 ...

随机推荐

  1. github.com使用方法

    github.com作为一个开源的代码托管平台,非常适合创建自己的代码库,也适合从别人已有项目fork自己的私有库:如果想私有托管,需要缴费使用. 创建自己代码库 在个人主页面,点击右上角+号,选择N ...

  2. 使用CocoaPods被卡住:Updating local specs repositories

    使用cocoapods 更新第三库,一直停留在.Updating local specs repositories 后来查发现pod install  被墙了,请大家换成pod install --v ...

  3. 加快XCode的编译链接速度(200%+)—XCode编译速度慢的解决方案

    最近在开发一个大项目的时候遇到一个很头疼的问题,由于项目代码较多,每次都要编译链接1分钟左右,调试的时候很浪费时间,于是研究了一下如何提高编译链接的速度,在这里分享给大家. 提升编译链接的速度主要有以 ...

  4. C#获取本地IP地址[常用代码段]

    获得当前机器的IP代码,假设本地主机为单网卡 string strHostName = Dns.GetHostName(); //得到本机的主机名 IPHostEntry ipEntry = Dns. ...

  5. django 进阶篇

    models(模型) 创建数据库,设计表结构和字段 使用 MySQLdb 来连接数据库,并编写数据访问层代码 业务逻辑层去调用数据访问层执行数据库操作 import MySQLdb def GetLi ...

  6. JavaScript中的类型转换

    1.隐式类型转换 ①== 如果相等操作的两个变量不是同一类型,那么相等运算符会尝试进行一些类型转换: 如果一个是null,一个是undefined,则他们相等: 如果一个值是数字,另一个是字符串,先将 ...

  7. Beta阶段第九次Scrum Meeting

    情况简述 BETA阶段第九次Scrum Meeting 敏捷开发起始时间 2017/1/2 00:00 敏捷开发终止时间 2017/1/3 00:00 会议基本内容摘要 deadline临近 参与讨论 ...

  8. Jquery datatables 使用方法

    说明: 1.s开头的是字符串 2.b开头的是布尔值 3.i开头的是整型值 4.o开头的是Json对象 5.ao开头的是Json对象数组 6.aa开头的是二维数组 7.fn开头的是函数 服务器端返回的数 ...

  9. NOIP2016游记

    只是游记而已.流水账. Day0:忘了. Day1:看完T1,本以为T2一如既往很简单,结果看了半天完全没有思路.然后看了一眼T3,期望,NOIP什么时候要考期望了,于是接着看T2.一开始我推的限制条 ...

  10. [转]mysql 视图

    转载自http://blog.csdn.net/evankaka/article/details/47071133 一. 视图概述 视图是一个虚拟表,其内容由查询定义.带来许多好处: 1. 视图能简化 ...