摘要:起步很多時候,需要把控制權(quán)限交給用戶,或者在擴(kuò)展里完成某件事后去回調(diào)用戶的方法。在擴(kuò)展里是通過函數(shù)來調(diào)用用戶空間的函數(shù)的。收集回調(diào)函數(shù)的返回值。回調(diào)函數(shù)需要傳遞參數(shù)的個數(shù)。利用語言多線程庫來實現(xiàn)一個簡單的并行擴(kuò)展。
起步
很多時候,需要把控制權(quán)限交給用戶,或者在擴(kuò)展里完成某件事后去回調(diào)用戶的方法。
在PHP擴(kuò)展里是通過 call_user_function_ex 函數(shù)來調(diào)用用戶空間的函數(shù)的。
定義它的定義在 Zend/zend_API.h :
#define call_user_function_ex(function_table, object, function_name, retval_ptr, param_count, params, no_separation, symbol_table) _call_user_function_ex(object, function_name, retval_ptr, param_count, params, no_separation)
通過宏定義替換為_call_user_function_ex,其中參數(shù) function_table 被移除了,它之所以在API才存在大概是為了兼容以前的寫法。函數(shù)的真正定義是:
ZEND_API int _call_user_function_ex( zval *object, zval *function_name, zval *retval_ptr, uint32_t param_count, zval params[], int no_separation);
參數(shù)分析:
zval *object:這個是用來我們調(diào)用類里的某個方法的對象。
zval *function_name:要調(diào)用的函數(shù)的名字。
zval *retval_ptr:收集回調(diào)函數(shù)的返回值。
uint32_t param_count:回調(diào)函數(shù)需要傳遞參數(shù)的個數(shù)。
zval params[]: 參數(shù)列表。
int no_separation:是否對zval進(jìn)行分離,如果設(shè)為1則直接會出錯,分離的作用是為了優(yōu)化空間。
回調(diào)功能的實現(xiàn)PHP_FUNCTION(hello_callback) { zval *function_name; zval retval; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &function_name) == FAILURE) { return; } if (Z_TYPE_P(function_name) != IS_STRING) { php_printf("Function require string argumnets!"); return; } //TSRMLS_FETCH(); if (call_user_function_ex(EG(function_table), NULL, function_name, &retval, 0, NULL, 0, NULL TSRMLS_CC) != SUCCESS) { php_printf("Function call failed!"); return; } *return_value = retval; zval_copy_ctor(return_value); zval_ptr_dtor(&retval); }
zval_copy_ctor()原始(zval)的內(nèi)容拷貝給它。zval_ptr_dtor()釋放空間。return_value不是一個函數(shù)外的變量,它的由函數(shù)聲明里的變量。PHP_FUNCTION(hello_callback)這個聲明是簡寫,最終會被預(yù)處理宏替換為:
void zif_hello_callback(zend_execute_data *execute_data, zval *return_value)
return_value變量其實也就是最終返回給調(diào)用腳本的,RETURN_STR(s) 等返回函數(shù)最終也都是宏替換為對該變量的操作。
測試腳本:
一個并行擴(kuò)展早期的php不支持多進(jìn)程多線程的,現(xiàn)在隨著發(fā)展有很多擴(kuò)展不斷完善它,諸如pthread,swoole等,不僅能多線程,而且能實現(xiàn)異步。
利用c語言多線程pthread庫來實現(xiàn)一個簡單的并行擴(kuò)展。
先聲明我們一會用到的結(jié)構(gòu):
struct myarg { zval *fun; zval ret; };線程函數(shù):
static void my_thread(struct myarg *arg) { zval *fun = arg->fun; zval ret = arg->ret; if (call_user_function_ex(EG(function_table), NULL, fun, &ret, 0, NULL, 0, NULL TSRMLS_CC) != SUCCESS) { return; } }函數(shù)的實現(xiàn):
PHP_FUNCTION(hello_thread) { pthread_t tid; zval *fun1, *fun2; zval ret1, ret2; struct myarg arg; int ret; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &fun1, &fun2) == FAILURE) { return; } arg.fun = fun1; arg.ret = ret1; ret = pthread_create(&tid, NULL, (void*)my_thread, (void*)&arg); if(ret != 0) { php_printf("Thread Create Error "); exit(0); } if (call_user_function_ex(EG(function_table), NULL, fun2, &ret2, 0, NULL, 0, NULL TSRMLS_CC) != SUCCESS) { return; } pthread_join(tid, NULL); RETURN_NULL(); }測試腳本:
輸出:
兩次的輸出結(jié)果不一樣,并且echo "after 多并發(fā)";是在兩個函數(shù)都運行完后才執(zhí)行的。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/22092.html
摘要:但在密集計算方面比等靜態(tài)編譯語言差幾十倍甚至上百倍。一使用棧內(nèi)存在引擎和擴(kuò)展中,經(jīng)常要創(chuàng)建一個的變量,底層就是一個指針。代碼中創(chuàng)建的變量也進(jìn)行了優(yōu)化,直接在棧內(nèi)存上預(yù)分配。應(yīng)用層與底層在錯誤拋出的方式全部統(tǒng)一為異常。 原文:http://rango.swoole.com/archives/440最近PHP官方終于發(fā)布了傳說中的PHP7,雖然只是alpha版。PHP7號稱是新一代的PHP...
摘要:目前來看等語言還難以企及和。作為一個資深的開發(fā)者,在技術(shù)上給各位程序十點未來的建議,希望對大家有所幫助。開發(fā)者應(yīng)當(dāng)學(xué)習(xí)掌握規(guī)范,在開發(fā)程序時應(yīng)當(dāng)盡量遵循規(guī)范。程序員除了寫后臺程序之外,還有很大一部分工作在展現(xiàn)層,和瀏覽器前端打交道。 PHP 從誕生到現(xiàn)在已經(jīng)有20多年歷史,從Web時代興起到移動互聯(lián)網(wǎng)退潮,互聯(lián)網(wǎng)領(lǐng)域各種編程語言和技術(shù)層出不窮, Node.js 、 GO 、 Pytho...
摘要:修復(fù)添加超過萬個以上定時器時發(fā)生崩潰的問題增加模塊,下高性能序列化庫修復(fù)監(jiān)聽端口設(shè)置無效的問題等。線程來處理網(wǎng)絡(luò)事件輪詢,讀取數(shù)據(jù)。當(dāng)?shù)娜挝帐殖晒α艘院?,由這個線程將連接成功的消息告訴進(jìn)程,再由進(jìn)程轉(zhuǎn)交給進(jìn)程。此時進(jìn)程觸發(fā)事件。 本文示例代碼詳見:https://github.com/52fhy/swoo...。 簡介 Swoole是一個PHP擴(kuò)展,提供了PHP語言的異步多線程服務(wù)器...
摘要:我們?yōu)榱颂幚磉@些挑戰(zhàn),提出了一個新的引用測試框架當(dāng)然,也是開源的,并且在整個過程中節(jié)省了上百萬美元。另一方面,被證實有一些嚴(yán)重的缺點部署困難而且慢。在緩存刷新期間,當(dāng)可用于別的進(jìn)程的已緩存的文件字節(jié)碼在此時損壞,就會導(dǎo)致崩潰。 How Badoo saved one million dollars switching to PHP7 我們成功的把我們的應(yīng)用遷移到了php7上面(數(shù)百臺機(jī)...
閱讀 1609·2021-11-04 16:11
閱讀 3328·2021-09-09 11:33
閱讀 1571·2019-08-30 15:54
閱讀 626·2019-08-30 15:44
閱讀 3185·2019-08-30 15:43
閱讀 2567·2019-08-30 13:06
閱讀 1707·2019-08-29 17:00
閱讀 908·2019-08-29 15:33