Perl 在XS中创建线程回调
编辑:我已经为此创建了一个数据库,其中有关于这种方式的替代方法的数据 我试图使用我的_CXT的回调,因为gcxt没有跨线程存储。但是,此段在回车时出错Perl 在XS中创建线程回调,perl,multithreading,xs,Perl,Multithreading,Xs,编辑:我已经为此创建了一个数据库,其中有关于这种方式的替代方法的数据 我试图使用我的_CXT的回调,因为gcxt没有跨线程存储。但是,此段在回车时出错 #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #ifndef aTHX_ #define aTHX_ #endif #ifdef USE_THREADS #define HAVE_TLS_CONTEXT #endif /* For windows */ #ifndef SD
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#ifndef aTHX_
#define aTHX_
#endif
#ifdef USE_THREADS
#define HAVE_TLS_CONTEXT
#endif
/* For windows */
#ifndef SDL_PERL_DEFINES_H
#define SDL_PERL_DEFINES_H
#ifdef HAVE_TLS_CONTEXT
PerlInterpreter *parent_perl = NULL;
extern PerlInterpreter *parent_perl;
#define GET_TLS_CONTEXT parent_perl = PERL_GET_CONTEXT;
#define ENTER_TLS_CONTEXT \
PerlInterpreter *current_perl = PERL_GET_CONTEXT; \
PERL_SET_CONTEXT(parent_perl); { \
PerlInterpreter *my_perl = parent_perl;
#define LEAVE_TLS_CONTEXT \
} PERL_SET_CONTEXT(current_perl);
#else
#define GET_TLS_CONTEXT /* TLS context not enabled */
#define ENTER_TLS_CONTEXT /* TLS context not enabled */
#define LEAVE_TLS_CONTEXT /* TLS context not enabled */
#endif
#endif
#include <SDL.h>
#define MY_CXT_KEY "SDL::Time::_guts" XS_VERSION
typedef struct {
void* data;
SV* callback;
Uint32 retval;
} my_cxt_t;
static my_cxt_t gcxt;
START_MY_CXT
static Uint32 add_timer_cb ( Uint32 interval, void* param )
{
ENTER_TLS_CONTEXT
dMY_CXT;
dSP;
int back;
ENTER; //SEGFAULTS RIGHT HERE!
SAVETMPS;
PUSHMARK(SP);
XPUSHs(sv_2mortal(newSViv(interval)));
PUTBACK;
if (0 != (back = call_sv(MY_CXT.callback,G_SCALAR))) {
SPAGAIN;
if (back != 1 ) Perl_croak (aTHX_ "Timer Callback failed!");
MY_CXT.retval = POPi;
} else {
Perl_croak(aTHX_ "Timer Callback failed!");
}
FREETMPS;
LEAVE;
LEAVE_TLS_CONTEXT
dMY_CXT;
return MY_CXT.retval;
}
MODULE = SDL::Time PACKAGE = SDL::Time PREFIX = time_
BOOT:
{
MY_CXT_INIT;
}
SDL_TimerID
time_add_timer ( interval, cmd )
Uint32 interval
void *cmd
PREINIT:
dMY_CXT;
CODE:
MY_CXT.callback=cmd;
gcxt = MY_CXT;
RETVAL = SDL_AddTimer(interval,add_timer_cb,(void *)cmd);
OUTPUT:
RETVAL
void
CLONE(...)
CODE:
MY_CXT_CLONE;
输出为
$
应该是
$ Never Prints
$time需要是一个共享变量-否则perl将使用该变量的单独副本。快速注释:
- 不要在Perl解释器对象的上下文之外使用Perl结构(SV、AV、HV等)。也就是说,不要将其用作C级静态数据。它将在线程上下文中爆炸。相信我,我去过那里
- 查看手册页中的“在XS中安全存储静态数据”部分
- 从perlapi的角度来看,你正在做的一些事情看起来相当不公开。不过我不太确定
嗯。。。我不知道你指的是什么。是否要编写一些代码?在末尾添加sleep 200,看看是否有输出。在设置计时器和打印$time之间是否应该有一个“睡眠”状态?如果您的程序没有阻塞,只是简单地跳回shell,这似乎是一个硬崩溃,否则perl不会完全失控。试着调试perl并在gdb中运行一些东西。好的,我正在尝试,但是没有什么能给我一个完全不同的想法。我已经把票附在这个问题上了。
$ Never Prints