Python论坛  - 讨论区

标题:[python-chinese] 嵌入python与线程

2006年04月21日 星期五 15:40

吴俊玉 wujunyu at gmail.com
Fri Apr 21 15:40:35 HKT 2006

总算对嵌入python有点了解了
写了一个代码和大家讨论一下

#include 

#include 



PyThreadState * mainThreadState;



unsigned long WINAPI run(void * arg)

{

     PyEval_AcquireLock();

     PyInterpreterState * mainInterpreter = mainThreadState->interp;

     PyThreadState * threadInfo = PyThreadState_New(mainInterpreter);

     *PyObject_CallMethod((PyObject *)arg, "run", NULL);*

*    //这里*有个奇怪的问题,就是如果我调用test方法,则能够正确返回,但是调用run方法――该方法在内部阻塞,则立即返回NULL

     //是不是python解释器不支持调用阻塞的函数?

     PyEval_ReleaseLock();

     return 0;

}



int main(int argc,char ** argv)

{

     Py_Initialize();

     PyEval_InitThreads();

     PyObject *TankModule = NULL;

     PyObject *TankDict = NULL;

     PyObject *TankClassObj = NULL;

     PyObject *TankObject = NULL;

     PyObject *ConstructArgs=NULL;

     mainThreadState = PyThreadState_Get();



     TankModule = PyImport_ImportModule("Tank");

     TankDict = PyModule_GetDict(TankModule);

     TankClassObj = PyDict_GetItemString(TankDict,"Tank");

     ConstructArgs=Py_BuildValue("iiiii",10,10,10,10,100);

     TankObject = PyObject_Call(TankClassObj, ConstructArgs, NULL);

     PyEval_ReleaseLock();

//这一段必不可少,因为Py_Initialize();主线程获得GIL,而tmpthread线程无法获得GIL被阻塞!

     HANDLE tmpthread=CreateThread(NULL,0,run,TankObject,0,NULL);

     WaitForSingleObject(tmpthread,INFINITE);

     Py_Finalize();

     return 0;
}

python脚本如下:

import threading

class Tank:#(threading.Thread):
    ee=threading.Event()
    def __init__(self,i,j,h,w,a):
        self.curX=i
        self.curY=j
        self.oldX=i
        self.oldY=j
        self.angle=a
        self.oldAngle=a
        self.arms=100

    def forward(self):
        if (self.angle==0):
            self.curX=self.curX+1
            self.oldX=self.curX
        if (self.angle==90):
            self.curY=self.curY-1
            self.oldY=self.curY
        if (self.angle==180):
            self.curX=self.curX-1
            self.oldX=self.curX
        if (self.angle==270):
            self.curY=self.curY+1
            self.oldY=self.curY
        ee.clear();

    def backward(self):
        if (self.angle==0):
            self.curX=self.curX-1
            self.oldX=self.curX
        if (self.angle==90):
            self.curY=self.curY+1
            self.oldY=self.curY
        if (self.angle==180):
            self.curX=self.curX+1
            self.oldX=self.curX
        if (self.angle==270):
            self.curY=self.curY-1
            self.oldY=self.curY
        ee.clear();

    def onHit(self):
        self.arms=self.arms-1

    def run(self):
        self.forward()

    def wakeup():
        ee.set();

    def test(self):
        return 'Test!'

但是我的程序
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.exoweb.net/pipermail/python-chinese/attachments/20060421/235924c1/attachment.html

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2006年04月21日 星期五 16:15

刘鑫 march.liu at gmail.com
Fri Apr 21 16:15:37 HKT 2006

读了您的代码,颇受启发,这里请教下,执行run的线程是以同步还是异步方式执行?因为我看到您的代码中,主线程先释放了GIL,那么如果我希望启动子线程后并不等待其结束,而是继续主线程,再次
PyEval_AcquireLock()的时候,会不会造成锁的争用?

在06-4-21,吴俊玉 <wujunyu at gmail.com> 写道:
>
> 总算对嵌入python有点了解了
> 写了一个代码和大家讨论一下
>
> #include 
>
> #include 
>
>
>
> PyThreadState * mainThreadState;
>
>
>
> unsigned long WINAPI run(void * arg)
>
> {
>
>      PyEval_AcquireLock();
>
>      PyInterpreterState * mainInterpreter = mainThreadState->interp;
>
>      PyThreadState * threadInfo = PyThreadState_New(mainInterpreter);
>
>      *PyObject_CallMethod((PyObject *)arg, "run", NULL);*
>
> *    //这里*有个奇怪的问题,就是如果我调用test方法,则能够正确返回,但是调用run方法――该方法在内部阻塞,则立即返回NULL
>
>      //是不是python解释器不支持调用阻塞的函数?
>
>      PyEval_ReleaseLock();
>
>      return 0;
>
> }
>
>
>
> int main(int argc,char ** argv)
>
> {
>
>      Py_Initialize();
>
>      PyEval_InitThreads();
>
>      PyObject *TankModule = NULL;
>
>      PyObject *TankDict = NULL;
>
>      PyObject *TankClassObj = NULL;
>
>      PyObject *TankObject = NULL;
>
>      PyObject *ConstructArgs=NULL;
>
>      mainThreadState = PyThreadState_Get();
>
>
>
>      TankModule = PyImport_ImportModule("Tank");
>
>      TankDict = PyModule_GetDict(TankModule);
>
>      TankClassObj = PyDict_GetItemString(TankDict,"Tank");
>
>      ConstructArgs=Py_BuildValue("iiiii",10,10,10,10,100);
>
>      TankObject = PyObject_Call(TankClassObj, ConstructArgs, NULL);
>
>      PyEval_ReleaseLock();
>
> //这一段必不可少,因为Py_Initialize();主线程获得GIL,而 tmpthread线程无法获得GIL被阻塞!
>
>      HANDLE tmpthread=CreateThread(NULL,0,run,TankObject,0,NULL);
>
>      WaitForSingleObject(tmpthread,INFINITE);
>
>      Py_Finalize();
>
>      return 0;
> }
>
> python脚本如下:
>
> import threading
>
> class Tank:#(threading.Thread):
>     ee=threading.Event()
>     def __init__(self,i,j,h,w,a):
>         self.curX=i
>         self.curY=j
>         self.oldX=i
>         self.oldY=j
>         self.angle=a
>         self.oldAngle=a
>         self.arms=100
>
>     def forward(self):
>         if (self.angle==0):
>             self.curX=self.curX+1
>             self.oldX=self.curX
>         if (self.angle==90):
>             self.curY=self.curY-1
>             self.oldY=self.curY
>         if (self.angle==180):
>             self.curX=self.curX-1
>             self.oldX=self.curX
>         if (self.angle==270):
>             self.curY=self.curY+1
>             self.oldY=self.curY
>         ee.clear();
>
>     def backward(self):
>         if (self.angle==0):
>             self.curX=self.curX-1
>             self.oldX=self.curX
>         if (self.angle==90):
>             self.curY=self.curY+1
>             self.oldY=self.curY
>         if (self.angle==180):
>             self.curX=self.curX+1
>             self.oldX=self.curX
>         if (self.angle==270):
>             self.curY=self.curY-1
>             self.oldY=self.curY
>         ee.clear();
>
>     def onHit(self):
>         self.arms=self.arms-1
>
>     def run(self):
>         self.forward()
>
>     def wakeup():
>         ee.set();
>
>     def test(self):
>         return 'Test!'
>
> 但是我的程序
>
>
>
>
>
>
> _______________________________________________
> python-chinese
> Post: send python-chinese at lists.python.cn
> Subscribe: send subscribe to python-chinese-request at lists.python.cn
> Unsubscribe: send unsubscribe to  python-chinese-request at lists.python.cn
> Detail Info: http://python.cn/mailman/listinfo/python-chinese
>
>


--
欢迎访问:
http://blog.csdn.net/ccat

刘鑫
March.Liu
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.exoweb.net/pipermail/python-chinese/attachments/20060421/44c3e255/attachment-0001.html

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2006年04月21日 星期五 20:10

吴俊玉 wujunyu at gmail.com
Fri Apr 21 20:10:33 HKT 2006

我现在是摸着石头过河啊,不过windows中主线程结束,必然清理子线程。因为是控制台程序,所以我用了
WaitForSingleObject(tmpthread,INFINITE);
我了解的不多也不敢乱说,就把我的想法说出来参考吧!
如果主线程不释放GIL,则子线程无法获得GIL而被阻塞。
如果某个线程已经获得GIL,再次调用PyEval_AcquireLock()应该不会阻塞
一个时间段内,只有一个线程被允许处理嵌入的python模块。

我也曾求助过子解释器,不过子解释器并不像我所想象的那么好用,似乎只是把对模块的修改独立开来,要解释执行脚本还需要GIL互斥访问

//-----------------------------------------------------------
我现在的麻烦就是管理GIL的问题了

至于

     *PyObject_CallMethod((PyObject *)arg, "run", NULL);*

*    //这里*有个奇怪的问题,就是如果我调用test方法,则能够正确返回,但是调用run方法――该方法在内部阻塞,则立即返回NULL

     //是不是python解释器不支持调用阻塞的函数?
这个问题,我也搞清楚了,如果能正确返回就搞笑了。
我的线程A先获得GIL,
然后调用函数阻塞自身,
然后在释放GIL


如果另外线程B负责唤醒线程A,而B又在等待GIL就容易发生死锁。


即使不发生死锁,这样也是不恰当的

不知道这么理解是不是符合python的设计初衷?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.exoweb.net/pipermail/python-chinese/attachments/20060421/5194022f/attachment.html

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2006年04月21日 星期五 20:18

吴俊玉 wujunyu at gmail.com
Fri Apr 21 20:18:22 HKT 2006

读了您的代码,颇受启发,这里请教下,执行run的线程是以同步还
是异步方式执行?因为我看到您的代码中,主线程先释放了GIL,那么如果我希望启动子线程后并不等待其结束,而是继续主线程,再次
PyEval_AcquireLock()的时候,会不会造成锁的争用?
//-----------------------------------------------------------------------------------------------------------------------------------------------
在这里使用主线程等待子线程结束是因为windows中主线程结束,必然清理子线程,在控制台程序中如果不等待子线程结束的话,子线程根本没有机会运行。如果是WIN32程序的话就可以不用等待,而同步执行。
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.exoweb.net/pipermail/python-chinese/attachments/20060421/44631e7e/attachment.html

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2006年04月22日 星期六 10:58

吴俊玉 wujunyu at gmail.com
Sat Apr 22 10:58:33 HKT 2006

继续这个问题:
我现在改成在python中创建线程,但是由于对python不是很了解,所以出现静态类成员的错误,还往各位指点一二
代码如下:

#include 
#include 
#include 

int main(int argc,char ** argv)
{
 Py_Initialize();
 PyEval_InitThreads();
 PyObject *TankModule = NULL;
 PyObject *TankDict = NULL;
 PyObject *TankClassObj = NULL;
 PyObject *TankObject = NULL;
 PyObject *ConstructArgs=NULL;

 TankModule = PyImport_ImportModule("Tank");
 TankDict = PyModule_GetDict(TankModule);
 TankClassObj = PyDict_GetItemString(TankDict,"Tank");
 ConstructArgs=Py_BuildValue("iii",10,10,0);
 TankObject = PyObject_Call(TankClassObj,ConstructArgs, NULL);
* PyObject * x = PyObject_CallMethod(TankObject, "start", NULL);
* Py_Finalize();
 std::cin.get();
 return 0;
}
python代码如下:

import threading

class Tank(threading.Thread):
*    ee=threading.Event()                      #类静态数据成员不是这么初始化吗?*
    def __init__(self,i,j,a):
        threading.Thread.__init__(self)
        self.curX=i
        self.curY=j
        self.oldX=i
        self.oldY=j
        self.angle=a
        self.oldAngle=a
        self.arms=100

    def forward(self):
        if (self.angle==0):
            self.curX=self.curX+1
            self.oldX=self.curX
        if (self.angle==90):
            self.curY=self.curY-1
            self.oldY=self.curY
        if (self.angle==180):
            self.curX=self.curX-1
            self.oldX=self.curX
        if (self.angle==270):
            self.curY=self.curY+1
            self.oldY=self.curY
        ee.clear()

    def backward(self):
        if (self.angle==0):
            self.curX=self.curX-1
            self.oldX=self.curX
        if (self.angle==90):
            self.curY=self.curY+1
            self.oldY=self.curY
        if (self.angle==180):
            self.curX=self.curX+1
            self.oldX=self.curX
        if (self.angle==270):
            self.curY=self.curY-1
            self.oldY=self.curY
        ee.clear()

    def onHit(self):
        self.arms=self.arms-1

    def run(self):
        print 'Run'
        self.forward()

    def wakeup(self):
        ee.set()

控制台错误输出如下:

Exception in thread Thread-1:
Traceback(most recent call last):
 File "python目录\threading.py",line 442, in __bootstrap
            self.run()
 File "工作目录\Tank.py",line 51, in run
            self.forward()
 File "工作目录\Tank.py",line 29, in forward
            ee.clear()
NameError: global name 'ee' is not defined

[9916 refs]
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.exoweb.net/pipermail/python-chinese/attachments/20060422/6704a1c6/attachment.html

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2006年04月22日 星期六 12:21

吴俊玉 wujunyu at gmail.com
Sat Apr 22 12:21:36 HKT 2006

原来类的静态数据成员要通过self.__class__.成员名访问

//----------------------------------------------------------------------------------
dive into python
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.exoweb.net/pipermail/python-chinese/attachments/20060422/5dabbeab/attachment.htm

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2006年04月22日 星期六 14:05

Robert Chen search.pythoner at gmail.com
Sat Apr 22 14:05:05 HKT 2006

主线程获得GIL并不是在Py_Initialize中,而是在PyEval_InitThread中。Python在默认启动时并没有激活其多线程机制,换句话说Py_Initialize中,甚至还没有创建GIL。GIL的创建和获得是在PyEval_InitThread中进行的:
void PyEval_InitThreads(void)
{
    if (interpreter_lock)
        return;
    interpreter_lock = PyThread_allocate_lock();
    PyThread_acquire_lock(interpreter_lock, 1);
    main_thread = PyThread_get_thread_ident();
}

interpreter_lock就是传说中的GIL,在win32平台下,Python内部实际上是通过win32下的Event内核对象实现的。PyThread_allocate_lock创建GIL,而PyThread_acquire_lock获得GIL
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.exoweb.net/pipermail/python-chinese/attachments/20060422/8d505013/attachment.html

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2006年04月22日 星期六 19:52

吴俊玉 wujunyu at gmail.com
Sat Apr 22 19:52:25 HKT 2006

总算要看到光明了,现在还有一个问题。
我希望能够获得类的数据成员,而不用通过成员函数返回――不过即使使用函数调用返回,估计也是一样的。
x= PyObject_GetAttrString(TankObject,"curX");
 int t;
 PyArg_ParseTuple(x,"i",&t;);

控制台输出的是x不是一个tuple。那x是什么呢?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.exoweb.net/pipermail/python-chinese/attachments/20060422/0b0ead4a/attachment.html

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2006年04月23日 星期日 01:20

Robert Chen search.pythoner at gmail.com
Sun Apr 23 01:20:53 HKT 2006

嗯,不是很明白你的问题.不过假如你的问题是x是个什么类型的对象,可以用下面的方法试一试:
在Python中,,以PyObject_为前缀的函数都属于Python向外部提供的一个抽象层的API,这个抽象层专职负责Python与C/C++
的交互。这些函数都以PyObject对象为参数,而如果有返回值,且是一个对象,则一定会是个PyObject*,所以x是一个PyObect*。
如果你熟悉PyObject的结构,那么就能访问到x所对应的类型对象的名字:
printf(x->ob_type->tp_name)
如果是x你在代码中所期望的tuple,那么会输出"tuple",不过我觉得不大可能是tuple,根据你第一封mail中看,这个输出结果很可能是"int",即x是一个PyIntObject对象,如果你想获得这个对象中所维护的那个整数,只需要这样t
= PyInt_AS_LONG(x)
即可。

关于Python中PyObject和PyIntObject的分析,可以参考我的《Python源码剖析》系列:)


On 4/22/06, 吴俊玉 <wujunyu at gmail.com> wrote:
>
> 总算要看到光明了,现在还有一个问题。
> 我希望能够获得类的数据成员,而不用通过成员函数返回――不过即使使用函数调用返回,估计也是一样的。
> x= PyObject_GetAttrString(TankObject,"curX");
>  int t;
>  PyArg_ParseTuple(x,"i",&t;);
>
> 控制台输出的是x不是一个tuple。那x是什么呢?
>
> _______________________________________________
> python-chinese
> Post: send python-chinese at lists.python.cn
> Subscribe: send subscribe to python-chinese-request at lists.python.cn
> Unsubscribe: send unsubscribe to  python-chinese-request at lists.python.cn
> Detail Info: http://python.cn/mailman/listinfo/python-chinese
>
>


--
Robert
Python源码剖析――http://blog.donews.com/lemur/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.exoweb.net/pipermail/python-chinese/attachments/20060423/1ed2a456/attachment.htm

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2006年04月23日 星期日 10:50

吴俊玉 wujunyu at gmail.com
Sun Apr 23 10:50:24 HKT 2006

到时一定拜读
昨晚用死方法硬是把他给搞定了
的确是PyIntObject
然后再通过PyInt_AsLong()转换成c语言中的int型。
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.exoweb.net/pipermail/python-chinese/attachments/20060423/9e716b60/attachment.html

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2006年04月23日 星期日 15:14

boyeestudio boyee118 at gmail.com
Sun Apr 23 15:14:50 HKT 2006

楼主是在Winodws下运作的吧。
能不能把GCC的Makefile共享一下!
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.exoweb.net/pipermail/python-chinese/attachments/20060423/a88004c4/attachment.html

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2006年04月23日 星期日 16:35

吴俊玉 wujunyu at gmail.com
Sun Apr 23 16:35:25 HKT 2006

抱歉没用gcc
windows下用的.net,
不过我有debug版的dll,原来使用的是vc6,为了这个debug版的dll升成了.net版本

然后再通过PyInt_AsLong()转换成c语言中的int型。
这条语句有问题,救命啊!!
看这个程序

#include 
#include 
#include 
#include 

int main(int argc,char ** argv)
{
 int t,i=0;
 std::fstream out("debug.txt");
 Py_Initialize();
 PyEval_InitThreads();
 PyObject *TankModule = NULL;
 PyObject *TankDict = NULL;
 PyObject *TankClassObj = NULL;
 PyObject *TankObject = NULL;
 PyObject *ConstructArgs=NULL;

 TankModule = PyImport_ImportModule("asd0");
 TankDict = PyModule_GetDict(TankModule);
 TankClassObj = PyDict_GetItemString(TankDict,"asd0");
 ConstructArgs=Py_BuildValue("iii",10,10,0);
 TankObject = PyObject_Call(TankClassObj,ConstructArgs, NULL);
 PyObject * x = PyObject_CallMethod(TankObject, "start", NULL);
 while(i<100)
 {
  x=PyObject_GetAttrString(TankObject,"curX");
  t=PyInt_AsLong(x);
  t=PyInt_AS_LONG(x);//这两条语句都差不多,反正是不能得到正确的值
  out<<<<http://lists.exoweb.net/pipermail/python-chinese/attachments/20060423/5cd34a6b/attachment.htm

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2006年04月23日 星期日 16:40

吴俊玉 wujunyu at gmail.com
Sun Apr 23 16:40:38 HKT 2006

而且Py_Finalize似乎并不终止线程,要自己终止?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.exoweb.net/pipermail/python-chinese/attachments/20060423/2925bfe3/attachment.html

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2006年04月23日 星期日 17:11

吴俊玉 wujunyu at gmail.com
Sun Apr 23 17:11:33 HKT 2006

线程的原因!

。。。。。。
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.exoweb.net/pipermail/python-chinese/attachments/20060423/858d85d7/attachment.htm

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2006年04月25日 星期二 10:20

Robert Chen search.pythoner at gmail.com
Tue Apr 25 10:20:08 HKT 2006

不是很清楚你的问题,建议描述得再详细一些 :)......

On 4/23/06, 吴俊玉 <wujunyu at gmail.com> wrote:
>
>  线程的原因!
>
> 。。。。。。
>
>
>
> _______________________________________________
> python-chinese
> Post: send python-chinese at lists.python.cn
> Subscribe: send subscribe to python-chinese-request at lists.python.cn
> Unsubscribe: send unsubscribe to  python-chinese-request at lists.python.cn
> Detail Info: http://python.cn/mailman/listinfo/python-chinese
>
>


--
Robert
Python源码剖析――http://blog.donews.com/lemur/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.exoweb.net/pipermail/python-chinese/attachments/20060425/bb5bff85/attachment.htm

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2006年04月25日 星期二 14:52

吴俊玉 wujunyu at gmail.com
Tue Apr 25 14:52:06 HKT 2006

这么说吧!
什么都不管看看下面这段程序那里有问题

import thread
import threading
class Tank:
     ee=threading.Event()
     def __init__(self,i):
          self.cur=i

    def forward(self):
          self.cur=self.cur+1
          self.__class__.ee.clear()

    def run(self):
          while(1):                                       //忽然想到这句话有没有问题啊?
               self.forward()

    def wakeup(self):
          self.__class__.ee.set()

    def start(self):
          thread.start_new_thread(self.run,())

if __name__=="__main__":
     a=Tank(123)
     a.start()
     i=1
     while(i<10):
          i=i+1
          a.wakeup()
          print a.cur

另外Python允许有类属性,也就相当java/c++中的静态数据
有没有静态方法呢?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.exoweb.net/pipermail/python-chinese/attachments/20060425/def212d9/attachment.html

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2006年04月25日 星期二 15:07

Zhang Fan yalexfan at gmail.com
Tue Apr 25 15:07:57 HKT 2006

Tank.ee 有什么用?


On 4/25/06, 吴俊玉 <wujunyu at gmail.com> wrote:
>
> 这么说吧!
> 什么都不管看看下面这段程序那里有问题
>
> import thread
> import threading
> class Tank:
>      ee=threading.Event()
>      def __init__(self,i):
>           self.cur=i
>
>     def forward(self):
>           self.cur=self.cur+1
>           self.__class__.ee.clear()
>
>     def run(self):
>           while(1):
> //忽然想到这句话有没有问题啊?
>                self.forward()
>
>     def wakeup(self):
>           self.__class__.ee.set()
>
>     def start(self):
>           thread.start_new_thread(self.run,())
>
> if __name__=="__main__":
>      a=Tank(123)
>      a.start()
>      i=1
>      while(i<10):
>           i=i+1
>           a.wakeup()
>           print a.cur
>
> 另外Python允许有类属性,也就相当java/c++中的静态数据
> 有没有静态方法呢?
> _______________________________________________
> python-chinese
> Post: send python-chinese at lists.python.cn
> Subscribe: send subscribe to
> python-chinese-request at lists.python.cn
> Unsubscribe: send unsubscribe to
> python-chinese-request at lists.python.cn
> Detail Info:
> http://python.cn/mailman/listinfo/python-chinese
>
>

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2006年04月25日 星期二 15:15

yi huang yi.codeplayer at gmail.com
Tue Apr 25 15:15:04 HKT 2006

ee=threading.Event() ,只看到set()和clear(), 不知道你用它干了点啥。
Tank线程不停给cur+1, 主线程读出了其10个值并输出。
问题应该没啥吧,就是不知道干了啥。

静态方法(staticmethod) 类方法(classmethod)    都是有的



On 4/25/06, 吴俊玉 <wujunyu at gmail.com> wrote:
>
> 这么说吧!
> 什么都不管看看下面这段程序那里有问题
>
> import thread
> import threading
> class Tank:
>      ee=threading.Event()
>      def __init__(self,i):
>           self.cur=i
>
>     def forward(self):
>           self.cur=self.cur+1
>           self.__class__.ee.clear()
>
>     def run(self):
>           while(1):                                       //忽然想到这句话有没有问题啊?
>                self.forward()
>
>     def wakeup(self):
>           self.__class__.ee.set()
>
>     def start(self):
>           thread.start_new_thread(self.run,())
>
> if __name__=="__main__":
>      a=Tank(123)
>      a.start()
>      i=1
>      while(i<10):
>           i=i+1
>           a.wakeup()
>           print a.cur
>
> 另外Python允许有类属性,也就相当java/c++中的静态数据
> 有没有静态方法呢?
>
> _______________________________________________
> python-chinese
> Post: send python-chinese at lists.python.cn
> Subscribe: send subscribe to python-chinese-request at lists.python.cn
> Unsubscribe: send unsubscribe to  python-chinese-request at lists.python.cn
> Detail Info: http://python.cn/mailman/listinfo/python-chinese
>
>


--
http://codeplayer.blogbus.com/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.exoweb.net/pipermail/python-chinese/attachments/20060425/09b54f8d/attachment.html

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2006年04月26日 星期三 09:46

Robert Chen search.pythoner at gmail.com
Wed Apr 26 09:46:36 HKT 2006

我运行了一下,你的意思是不是输出了10个相同的数值,比如:123,123,...,123
但是你期望的应该是:123,124,...,133?

这个与Python内核中的线程调度机制有关。简要地说,在主线程创建子线程是,它手里攥着GIL,thread.start_new_thread确实创建了子线程,但是创建完成的子线程并不会立即进入你在run中定义的那个循环,准确地说,子线程的运行路径在进入Python字节码解释器PyEval_EvalFrame之前,就因为等待GIL而被挂起,这个时候,GIL在主线程手里。

在操作系统中,线程的切换是由时钟中断触发的,在Python内核中,有一个软件模拟的时钟中断。确切地说,在Python内部,维护着一个变量_Py_Ticker,Python解释器每执行一条字节码,就会将其递减,当其变为0时,Python的线程调度才被触发。
在Python2.4当中,这个变量的初始值为100。你可以通过sys.getcheckinterval()来获得这个值。

现在的问题是,你的主线程在_Py_Ticker变为0之前就已经结束了,而这时子线程甚至还没有进入PyEval_EvalFrame,所以改变self.cur就更无从谈起。
你可以在主线程和子线程的主循环中加入time.sleep(0),执行这条语句会使活动线程自动阻塞,从而触发Python的线程调度机制。


On 4/25/06, 吴俊玉 <wujunyu at gmail.com> wrote:
>
>  这么说吧!
> 什么都不管看看下面这段程序那里有问题
>
> import thread
> import threading
> class Tank:
>      ee=threading.Event()
>      def __init__(self,i):
>           self.cur=i
>
>     def forward(self):
>           self.cur=self.cur+1
>           self.__class__.ee.clear()
>
>     def run(self):
>           while(1):                                       //忽然想到这句话有没有问题啊?
>                 self.forward()
>
>     def wakeup(self):
>            self.__class__.ee.set()
>
>     def start(self):
>           thread.start_new_thread(self.run,())
>
> if __name__=="__main__":
>      a=Tank(123)
>      a.start()
>      i=1
>      while(i<10):
>           i=i+1
>           a.wakeup()
>           print a.cur
>
> 另外Python允许有类属性,也就相当java/c++中的静态数据
> 有没有静态方法呢?
>
> _______________________________________________
> python-chinese
> Post: send python-chinese at lists.python.cn
> Subscribe: send subscribe to python-chinese-request at lists.python.cn
> Unsubscribe: send unsubscribe to  python-chinese-request at lists.python.cn
> Detail Info: http://python.cn/mailman/listinfo/python-chinese
>
>


--
Robert
Python源码剖析――http://blog.donews.com/lemur/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.exoweb.net/pipermail/python-chinese/attachments/20060426/4e773526/attachment.html

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2006年04月26日 星期三 09:53

吴俊玉 wujunyu at gmail.com
Wed Apr 26 09:53:14 HKT 2006

你的解释每次都能让我学到东西,
论文快要答辩了,原型也基本完成了。

上面提到的问题是对Event理解错误导致的。
我使用了clear()来阻塞线程了

这当然不可行了。
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.exoweb.net/pipermail/python-chinese/attachments/20060426/c9730080/attachment.html

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2006年04月28日 星期五 09:28

吴俊玉 wujunyu at gmail.com
Fri Apr 28 09:28:23 HKT 2006

不知道是不是该重开一个邮件标题,不过也属于合作的问题。

python的功能很强大,有没有办法限制他的这种强大呢?

比如说在嵌入的python中不能进行系统调用,等等。
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.exoweb.net/pipermail/python-chinese/attachments/20060428/95c8eab6/attachment.htm

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

如下红色区域有误,请重新填写。

    你的回复:

    请 登录 后回复。还没有在Zeuux哲思注册吗?现在 注册 !

    Zeuux © 2025

    京ICP备05028076号