2012-10-10 134 views
2

我正在为GPIO驱动程序提供的功能编写Python extension。我在set_bit()和clear_bit()这样的简单函数上轻松取得了进展。但是现在我需要实现wait_int(),这个睡眠直到在输入引脚上检测到一个事件,我不确定在c和python之间编排这条命令的正确方法。下面是在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非常直接,然后为所欲为无限循环的蟒蛇相当于成语是什么?还有一些需要解决的问题。我已经在c做了它,但也许它可以被移到python一侧。

回答

3

你不需要在Python方面做任何事情,你可以把它当作一个同步函数。在C方面,你只是阻塞,直到事件发生,可能允许中断。例如,看看在time.sleep功能的implementation

/* 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功能睡的时间一定时间。使用select,以便如果收到任何信号(例如在终端上按Ctrl + C的SIGINT),系统调用将中断并且控制返回到Python。

因此。你的实现可以调用C wait_int函数。如果它支持被信号中断,那么将会允许用户通过按Ctrl + C来中断它,但是要确保做出适当的反应,以便抛出异常(我不确定这是如何工作的,但是它看起来像从顶层函数返回NULL(在这个例子中为time_sleep)将做到这一点)。

同样,为了更好的多线程性能,请用一对Py_BEGIN_ALLOW_THREADS/Py_END_ALLOW_THREADS宏等待电话,但不是必需的,特别是如果你不使用多线程的。

+0

很简单。而True:wait_int() – tladuke

+0

如果我把它放在python线程中,它会阻塞任何其他线程,直到出现中断为止。 – tladuke

+0

Py_BEGIN_ALLOW_THREADS修正了它。 – tladuke