php扩展中如何定义线程安全的全局对象

简介:

传统的php裁剪类只能按位置裁剪。如按中间位置裁剪。这种裁剪方式可能会导致一个人被截成两段。为了解决这个问题,最近开发了一个php扩展(tclip),能自动识别人脸或者图像中其它重要区域,然后进行裁剪。裁剪效果如下:

原图:
a1

如果按照从中间截取为 400 * 225 大小大图片。效果如下:
a2

使用tclip扩展裁剪图片效果如下:
a3

在人脸识别的过程中,需要使用opencv中的CascadeClassifier加载一个xml的配置文档。因为文档比较大,导致加载时间比较长。为了提高裁剪的效率,决定在php扩展初始化的时候加载,并使用全局变量存储这个CascadeClassifier对象。这样就可以在每次裁剪的时候直接使用这个配置文件,而无需再加载。

开始,把php_tclip.h中的全局变量声明部分修改为如下:


ZEND_BEGIN_MODULE_GLOBALS(tclip)
    CascadeClassifier face_cascade;
    char *face_config_path;
ZEND_END_MODULE_GLOBALS(tclip)

结果报如下错误:
error: ‘CascadeClassifier’ does not name a type
看来这个类没有在头文件中声明。那就另辟蹊径,改为其它方式。把代码改为:


ZEND_BEGIN_MODULE_GLOBALS(tclip)
    void *face_cascade;
    char *face_config_path;
ZEND_END_MODULE_GLOBALS(tclip)

然后在tclip.c中进行了如下修改:
1.首先定义了一个全局变量。


static CascadeClassifier face_cascade;

2.修改PHP_MINIT_FUNCTION(tclip)。代码如下:


PHP_MINIT_FUNCTION(tclip)
{
    /* If you have INI entries, uncomment these lines */
    REGISTER_INI_ENTRIES();
     
    string face_config_path = (TCLIP_G(face_config_path) == "" || TCLIP_G(face_config_path) == NULL)? "/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml" :TCLIP_G(face_config_path);
    if( !face_cascade.load( face_config_path ) ){ 
        php_error_docref(NULL TSRMLS_CC, E_WARNING, "can not load classifier file!%s", face_config_path.c_str());
        return FAILURE; 
    }
    TCLIP_G(face_cascade) = &face_cascade;
    return SUCCESS;
}

调用全局对象的方式如下:


((CascadeClassifier *)TCLIP_G(face_cascade))->detectMultiScale( img_gray, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) );

注意,php扩展想线程安全,那就用相关宏来访问全局变量。如上面的TCLIP_G(face_cascade)。


目录
相关文章
|
1月前
|
缓存 安全 PHP
PHP中的魔术方法与对象序列化
本文将深入探讨PHP中的魔术方法,特别是与对象序列化和反序列化相关的__sleep()和__wakeup()方法。通过实例解析,帮助读者理解如何在实际应用中有效利用这些魔术方法,提高开发效率和代码质量。
|
2月前
|
设计模式 算法 数据库连接
PHP中的设计模式:提高代码的可维护性与扩展性本文旨在探讨PHP中常见的设计模式及其应用,帮助开发者编写出更加灵活、可维护和易于扩展的代码。通过深入浅出的解释和实例演示,我们将了解如何使用设计模式解决实际开发中的问题,并提升代码质量。
在软件开发过程中,设计模式是一套经过验证的解决方案模板,用于处理常见的软件设计问题。PHP作为流行的服务器端脚本语言,也有其特定的设计模式应用。本文将重点介绍几种PHP中常用的设计模式,包括单例模式、工厂模式和策略模式,并通过实际代码示例展示它们的具体用法。同时,我们还将讨论如何在实际项目中合理选择和应用这些设计模式,以提升代码的可维护性和扩展性。
61 4
|
8天前
|
消息中间件 缓存 监控
在PHP中,实现多线程
在PHP中,实现多线程
21 6
|
1月前
|
Java 应用服务中间件
面对海量网络请求,Tomcat线程池如何进行扩展?
【10月更文挑战第4天】本文详细探讨了Tomcat线程池相较于标准Java实用工具包(JUC)线程池的关键改进。首先,Tomcat线程池在启动时即预先创建全部核心线程,以应对启动初期的高并发请求。其次,通过重写阻塞队列的入队逻辑,Tomcat能够在任务数超过当前线程数但未达最大线程数时,及时创建非核心线程,而非等到队列满才行动。此外,Tomcat还引入了在拒绝策略触发后重新尝试入队的机制,以提高吞吐量。这些优化使得Tomcat线程池更适应IO密集型任务,有效提升了性能。
面对海量网络请求,Tomcat线程池如何进行扩展?
|
25天前
|
NoSQL 安全 Linux
MongoDB PHP 扩展
10月更文挑战第19天
12 0
MongoDB PHP 扩展
|
2月前
|
SQL 关系型数据库 数据库连接
php连接数据库之PDO,PDO的简单使用和预定义占位符的使用以及PDOStatement对象的使用,占位符的不同形式,bindValue和bindParam绑定预定义占位符参数的区别
本文介绍了PHP中PDO(PHP Data Objects)扩展的基本概念和使用方法。内容包括PDO类和PDOStatement类的介绍,PDO的简单使用,预定义占位符的使用方法,以及PDOStatement对象的使用。文章还讨论了绑定预定义占位符参数的不同形式,即bindValue和bindParam的区别。通过具体示例,展示了如何使用PDO进行数据库连接、数据查询、数据插入等操作。
php连接数据库之PDO,PDO的简单使用和预定义占位符的使用以及PDOStatement对象的使用,占位符的不同形式,bindValue和bindParam绑定预定义占位符参数的区别
|
2月前
|
PHP
PHP中如何比较两个对象
PHP中如何比较两个对象
|
2月前
|
PHP
PHP中的面向对象编程:理解类与对象
本文将深入探讨PHP中面向对象编程的核心概念——类与对象。通过实例讲解,帮助读者更好地理解如何在PHP中运用OOP编写更高效、可维护的代码。
45 9
|
2月前
|
存储 Java 程序员
优化Java多线程应用:是创建Thread对象直接调用start()方法?还是用个变量调用?
这篇文章探讨了Java中两种创建和启动线程的方法,并分析了它们的区别。作者建议直接调用 `Thread` 对象的 `start()` 方法,而非保持强引用,以避免内存泄漏、简化线程生命周期管理,并减少不必要的线程控制。文章详细解释了这种方法在使用 `ThreadLocal` 时的优势,并提供了代码示例。作者洛小豆,文章来源于稀土掘金。
|
2月前
|
设计模式 存储 算法
PHP中的设计模式:策略模式的深入解析与应用在软件开发的浩瀚海洋中,PHP以其独特的魅力和强大的功能吸引了无数开发者。作为一门历史悠久且广泛应用的编程语言,PHP不仅拥有丰富的内置函数和扩展库,还支持面向对象编程(OOP),为开发者提供了灵活而强大的工具集。在PHP的众多特性中,设计模式的应用尤为引人注目,它们如同精雕细琢的宝石,镶嵌在代码的肌理之中,让程序更加优雅、高效且易于维护。今天,我们就来深入探讨PHP中使用频率颇高的一种设计模式——策略模式。
本文旨在深入探讨PHP中的策略模式,从定义到实现,再到应用场景,全面剖析其在PHP编程中的应用价值。策略模式作为一种行为型设计模式,允许在运行时根据不同情况选择不同的算法或行为,极大地提高了代码的灵活性和可维护性。通过实例分析,本文将展示如何在PHP项目中有效利用策略模式来解决实际问题,并提升代码质量。