用于休眠函数的Python C扩展

用于休眠函数的Python C扩展,python,c,Python,C,我正在为GPIO驱动程序提供的函数编写一个脚本。我在set_bit()和clear_bit()等简单函数上取得了相当轻松的进展。但现在我需要实现wait_int(),它会一直休眠,直到在输入引脚上检测到一个事件,我不确定在c和python之间协调该事件的正确方法。下面是一个在c中使用函数的简单示例: main(int argc, char *argv[]) { int c; //some setup like testing port availability, clearin

我正在为GPIO驱动程序提供的函数编写一个脚本。我在set_bit()和clear_bit()等简单函数上取得了相当轻松的进展。但现在我需要实现wait_int(),它会一直休眠,直到在输入引脚上检测到一个事件,我不确定在c和python之间协调该事件的正确方法。下面是一个在c中使用函数的简单示例:

main(int argc, char *argv[])
{
    int c;

    //some setup like testing port availability, clearing interrupts, etc
    ...

    while(1)
    {
        printf("**\n");
        c = wait_int(1);//sleeps until an interrupt occurs on chip 1
        if(c > 0) {
            printf("Event sense occured on Chip 1 bit %d\n",c);
            ++event_count;
        }
        else
            break;
    }

    printf("Event count = %05d\r",event_count);
    printf("\nExiting Now\n");
}

我是否直接公开wait_int,然后执行与无限循环类似的python惯用法?还需要做一些去抖动的工作。我已经用c语言完成了,但也许可以将它移到python端。

您不需要在python端执行任何操作,只需将其视为一个同步函数即可。在C端,您只需阻塞直到事件发生,可能允许中断。例如,请查看函数的

/* LICENSE: http://docs.python.org/license.html */

/* Implement floatsleep() for various platforms.
   When interrupted (or when another error occurs), return -1 and
   set an exception; else return 0. */

static int
floatsleep(double secs)
{
/* XXX Should test for MS_WINDOWS first! */
#if defined(HAVE_SELECT) && !defined(__BEOS__) && !defined(__EMX__)
    struct timeval t;
    double frac;
    frac = fmod(secs, 1.0);
    secs = floor(secs);
    t.tv_sec = (long)secs;
    t.tv_usec = (long)(frac*1000000.0);
    Py_BEGIN_ALLOW_THREADS
    if (select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t) != 0) {
#ifdef EINTR
        if (errno != EINTR) {
#else
        if (1) {
#endif
            Py_BLOCK_THREADS
            PyErr_SetFromErrno(PyExc_IOError);
            return -1;
        }
    }
    Py_END_ALLOW_THREADS
#elif defined(__WATCOMC__) && !defined(__QNX__)
    ...
它所做的只是使用
select
功能在给定的时间段内睡眠<使用code>select,这样,如果接收到来自在终端点击Ctrl+C的任何信号(例如,
SIGINT
),系统调用将中断,控制将返回Python

因此。您的实现只需调用C
wait\u int
函数即可。如果它支持被信号中断,那么这将允许用户通过按Ctrl+C来中断它,但要确保做出适当的反应,以便抛出异常(我不确定这是如何工作的,但它看起来像是从顶级函数返回
NULL
time\u sleep
)会成功的)


同样,为了获得更好的多线程性能,可以在等待调用中使用一对
Py\u BEGIN\u ALLOW\u线程
/
Py\u END\u ALLOW\u线程
宏,但这并不是必需的,尤其是当您根本不使用多线程时。

这很容易。True:wait_int()如果我把它放在python线程中,它会阻止任何其他线程,直到出现中断。Py_BEGIN_ALLOW_threads修复了它。