Python如何实现线程间通信_python

来源:脚本之家  责任编辑:小易  

属于混合编程的问题。较全面的介绍一下,不仅限于题主提出的问题。以下讨论中,Python指它的标准实现,即CPython(虽然不是很严格)本文分4个部分C/C++ 调用 Python (基础篇)— 仅讨论Python官方提供的实现方式Python 调用 C/C++ (基础篇)— 仅讨论Python官方提供的实现方式C/C++ 调用 Python (高级篇)— 使用 CythonPython 调用 C/C++ (高级篇)— 使用 SWIG练习本文中的例子,需要搭建Python扩展开发环境。具体细节见搭建Python扩展开发环境 - 蛇之魅惑 - 知乎专栏1 C/C++ 调用 Python(基础篇)Python 本身就是一个C库。你所看到的可执行体python只不过是个stub。真正的python实体在动态链接库里实现,在Windows平台上,这个文件位于 %SystemRoot%\System32\python27.dll。你也可以在自己的程序中调用Python,看起来非常容易://my_python.c#include <Python.h>int main(int argc, char *argv[]){ Py_SetProgramName(argv[0]); Py_Initialize(); PyRun_SimpleString("print 'Hello Python!'\n"); Py_Finalize(); return 0;}在Windows平台下,打开Visual Studio命令提示符,编译命令为cl my_python.c -IC:\Python27\include C:\Python27\libs\python27.lib在Linux下编译命令为gcc my_python.c -o my_python -I/usr/include/python2.7/ -lpython2.7在Mac OS X 下的编译命令同上产生可执行文件后,直接运行,结果为输出Hello Python!Python库函数PyRun_SimpleString可以执行字符串形式的Python代码。虽然非常简单,但这段代码除了能用C语言动态生成一些Python代码之外,并没有什么用处。我们需要的是C语言的数据结构能够和Python交互。下面举个例子,比如说,有一天我们用Python写了一个功能特别强大的函数:def great_function(a): return a + 1接下来要把它包装成C语言的函数。我们期待的C语言的对应函数应该是这样的:int great_function_from_python(int a) { int res; // some magic return res;}首先,复用Python模块得做‘import’,这里也不例外。所以我们把great_function放到一个module里,比如说,这个module名字叫 great_module.py接下来就要用C来调用Python了,完整的代码如下:#include <Python.h>int great_function_from_python(int a) { int res; PyObject *pModule,*pFunc; PyObject *pArgs, *pValue; /* import */ pModule = PyImport_Import(PyString_FromString("great_module")); /* great_module.great_function */ pFunc = PyObject_GetAttrString(pModule, "great_function"); /* build args */ pArgs = PyTuple_New(1); PyTuple_SetItem(pArgs,0, PyInt_FromLong(a)); /* call */ pValue = PyObject_CallObject(pFunc, pArgs); res = PyInt_AsLong(pValue); return res;}从上述代码可以窥见Python内部运行的方式:所有Python元素,module、function、tuple、string等等,实际上都是PyObject。C语言里操纵它们,一律使用PyObject *。Python的类型与C语言类型可以相互转换。Python类型XXX转换为C语言类型YYY要使用PyXXX_AsYYY函数;C类型YYY转换为Python类型XXX要使用PyXXX_FromYYY函数。也可以创建Python类型的变量,使用PyXXX_New可以创建类型为XXX的变量。若a是Tuple,则a[i] = b对应于 PyTuple_SetItem(a,i,b),有理由相信还有一个函数PyTuple_GetItem完成取得某一项的值。不仅Python语言很优雅,Python的库函数API也非常优雅。现在我们得到了一个C语言的函数了,可以写一个main测试它#include <Python.h>int great_function_from_python(int a); int main(int argc, char *argv[]) { Py_Initialize(); printf("%d",great_function_from_python(2)); Py_Finalize();}编译的方式就用本节开头使用的方法。在Linux/Mac OSX运行此示例之前,可能先需要设置环境变量:bash:export PYTHONPATH=.:$PYTHONPATHcsh:setenv PYTHONPATH .:$PYTHONPATH2 Python 调用 C/C++(基础篇)这种做法称为Python扩展。比如说,我们有一个功能强大的C函数:int great_function(int a) { return a + 1;}期望在Python里这样使用:>>> from great_module import great_function >>> great_function(2)3考虑最简单的情况。我们把功能强大的函数放入C文件 great_module.c 中。#include <Python.h>int great_function(int a) { return a + 1;}static PyObject * _great_function(PyObject *self, PyObject *args){ int _a; int res; if (!PyArg_ParseTuple(args, "i", &_a)) return NULL; res = great_function(_a); return PyLong_FromLong(res);}static PyMethodDef GreateModuleMethods[] = { { "great_function", _great_function, METH_VARARGS, "" }, {NULL, NULL, 0, NULL}};PyMODINIT_FUNC initgreat_module(void) { (void) Py_InitModule("great_module", GreateModuleMethods);}除了功能强大的函数great_function外,这个文件中还有以下部分:包裹函数_great_function。它负责将Python的参数转化为C的参数(PyArg_ParseTuple),调用实际的great_function,并处理great_function的返回值,最终返回给Python环境。导出表GreateModuleMethods。它负责告诉Python这个模块里有哪些函数可以被Python调用。导出表的名字可以随便起,每一项有4个参数:第一个参数是提供给Python环境的函数名称,第二个参数是_great_function,即包裹函数。第三个参数的含义是参数变长,第四个参数是一个说明性的字符串。导出表总是以{NULL, NULL, 0, NULL}结束。导出函数initgreat_module。这个的名字不是任取的,是你的module名称添加前缀init。导出函数中将模块名称与导出表进行连接www.zgxue.com防采集请勿采集本网。

问题

你的程序中有多个线程,你需要在这些线程之间安全地交换信息或数据

不要谈什么qt,这个我不懂,但是就谈一谈线程的本质,那都是一样的,2个线程不可能同时进行这个是正确的,但是多核处理器除外。你所说的post和send,我不知道可不可以这么理解

解决方案

打开串口后启动一个线程来监听串口数据的进入,有数据时,就做数据的处理。 用python写串口通信程序的示例:#coding=gb18030  import sys,threading,time;  impo

从一个线程向另一个线程发送数据最安全的方式可能就是使用 queue 库中的队列了。创建一个被多个线程共享的 Queue 对象,这些线程通过使用 put() 和 get() 操作来向队列中添加或者删除元素。 例如:

Java多线程间的通信 Java还提供了一种线程间通信的机制,这种通信通什么实现? wait,notify等机制 或使用pipeInputStream和pipeOutputStream 1. 线程的几种状态 线程有四种

from queue import Queuefrom threading import Thread# A thread that produces datadef producer(out_q): while True: # Produce some data ... out_q.put(data)# A thread that consumes datadef consumer(in_q): while True:# Get some data data = in_q.get() # Process the data ...# Create the shared queue and launch both threadsq = Queue()t1 = Thread(target=consumer, args=(q,))t2 = Thread(target=producer, args=(q,))t1.start()t2.start()

线程间通信就是通过全局变量啊,线程之间没有“通信”的说法吧,不管有几个线程,它们都是在同一个进程地址空间内,都共享同样的内存空间,所以“通信”的说法才多见于进程

Queue 对象已经包含了必要的锁,所以你可以通过它在多个线程间多安全地共享数据。 当使用队列时,协调生产者和消费者的关闭问题可能会有一些麻烦。一个通用的解决方法是在队列中放置一个特殊的值,当消费者读到这个值的时候,终止执行。例如:

SetEvent SendMessage/PostMessage CRITICAL_SECTION Mutex

from queue import Queuefrom threading import Thread# Object that signals shutdown_sentinel = object()# A thread that produces datadef producer(out_q): while running: # Produce some data ... out_q.put(data) # Put the sentinel on the queue to indicate completion out_q.put(_sentinel)# A thread that consumes datadef consumer(in_q): while True: # Get some data data = in_q.get() # Check for termination if data is _sentinel: in_q.put(_sentinel) break # Process the data ...

知识点:UI只能由创建这个UI的线程所控制,说UI只能由主线程控制不完全正确,原因是绘制逻辑造成的,这里就不深究了,喜欢这个的可以百度 解决问题关键字: C# 多线程 传值

本例中有一个特殊的地方:消费者在读到这个特殊值之后立即又把它放回到队列中,将之传递下去。这样,所有监听这个队列的消费者线程就可以全部关闭了。 尽管队列是最常见的线程间通信机制,但是仍然可以自己通过创建自己的数据结构并添加所需的锁和同步机制来实现线程间通信。最常见的方法是使用 Condition 变量来包装你的数据结构。下边这个例子演示了如何创建一个线程安全的优先级队列

-线程:" + label + " 始工作------"); } catch (InterruptedException e) { e.printStackTrace(); } int num = 0; while (true) { System.out.println("线程:"

import heapqimport threadingclass PriorityQueue: def __init__(self): self._queue = [] self._count = 0 self._cv = threading.Condition() def put(self, item, priority): with self._cv: heapq.heappush(self._queue, (-priority, self._count, item)) self._count += 1 self._cv.notify() def get(self): with self._cv: while len(self._queue) == 0: self._cv.wait() return heapq.heappop(self._queue)[-1]

Java多线程间的通信 Java还提供了一种线程间通信的机制,这种通信通什么实现? wait,notify等机制 或使用pipeInputStream和pipeOutputStream 1. 线程的几种状态 线程有四

使用队列来进行线程间通信是一个单向、不确定的过程。通常情况下,你没有办法知道接收数据的线程是什么时候接收到的数据并开始工作的。不过队列对象提供一些基本完成的特性,比如下边这个例子中的 task_done() join()

WPF中不能直接操作UI主线程,要用Dispatcher

from queue import Queuefrom threading import Thread# A thread that produces datadef producer(out_q): while running: # Produce some data ... out_q.put(data)# A thread that consumes datadef consumer(in_q): while True: # Get some data data = in_q.get() # Process the data ... # Indicate completion in_q.task_done()# Create the shared queue and launch both threadsq = Queue()t1 = Thread(target=consumer, args=(q,))t2 = Thread(target=producer, args=(q,))t1.start()t2.start()# Wait for all produced items to be consumedq.join()

不是几句话能说的清楚的,给你个网址,上面有孙鑫老师的视频,其中有一章内容讲解的线程,很详细了。www.sunxin.org

如果一个线程需要在一个“消费者”线程处理完特定的数据项时立即得到通知,你可以把要发送的数据和一个 Event 放到一起使用,这样“生产者”就可以通过这个Event对象来监测处理的过程了。示例如下:

线程间通讯(三种方式):: public class AnrActivity extends Activity implements OnClickLis case R.id.button3: // 通过 new Thread()或者runOnUiThread()或者Handler 实现 ne

from queue import Queuefrom threading import Thread, Event# A thread that produces datadef producer(out_q): while running: # Produce some data ... # Make an (data, event) pair and hand it to the consumer evt = Event() out_q.put((data, evt)) ... # Wait for the consumer to process the item evt.wait()# A thread that consumes datadef consumer(in_q): while True: # Get some data data, evt = in_q.get() # Process the data ... # Indicate completion evt.set()

最简单的办法是,开个定时,在定时器中随时监事串口的数据流.并做相应的处理.

讨论

基于简单队列编写多线程程序在多数情况下是一个比较明智的选择。从线程安全队列的底层实现来看,你无需在你的代码中使用锁和其他底层的同步机制,这些只会把你的程序弄得乱七八糟。此外,使用队列这种基于消息的通信机制可以被扩展到更大的应用范畴,比如,你可以把你的程序放入多个进程甚至是分布式系统而无需改变底层的队列结构。 使用线程队列有一个要注意的问题是,向队列中添加数据项时并不会复制此数据项,线程间通信实际上是在线程间传递对象引用。如果你担心对象的共享状态,那你最好只传递不可修改的数据结构(如:整型、字符串或者元组)或者一个对象的深拷贝。例如:

按照下面这个运行结果(最后两行顺序不一定): 小张 用 20 元买票 小孙 用 10 元买票 小孙 买到票并拿回 5 元 小赵 用 5 元买票 小赵 买到票并拿回 0 元 小张 买到票并拿

from queue import Queuefrom threading import Threadimport copy# A thread that produces datadef producer(out_q): while True: # Produce some data ... out_q.put(copy.deepcopy(data))# A thread that consumes datadef consumer(in_q): while True: # Get some data data = in_q.get() # Process the data ...

这就需要4个线程,A对应服务器线程AA B对应服务器线程BB 其实是A发信息(里面包装发送目标)给AA AA再通过发送目标找到负责这个发送目标的线程BB AA发送信息给BB 然

Queue 对象提供一些在当前上下文很有用的附加特性。比如在创建 Queue 对象时提供可选的 size 参数来限制可以添加到队列中的元素数量。对于“生产者”与“消费者”速度有差异的情况,为队列中的元素数量添加上限是有意义的。比如,一个“生产者”产生项目的速度比“消费者” “消费”的速度快,那么使用固定大小的队列就可以在队列已满的时候阻塞队列,以免未预期的连锁效应扩散整个程序造成死锁或者程序运行失常。在通信的线程之间进行“流量控制”是一个看起来容易实现起来困难的问题。如果你发现自己曾经试图通过摆弄队列大小来解决一个问题,这也许就标志着你的程序可能存在脆弱设计或者固有的可伸缩问题。 get() put() 方法都支持非阻塞方式和设定超时,例如:

import queueq = queue.Queue()try: data = q.get(block=False)except queue.Empty: ...try: q.put(item, block=False)except queue.Full: ...try: data = q.get(timeout=5.0)except queue.Empty: ...

这些操作都可以用来避免当执行某些特定队列操作时发生无限阻塞的情况,比如,一个非阻塞的 put() 方法和一个固定大小的队列一起使用,这样当队列已满时就可以执行不同的代码。比如输出一条日志信息并丢弃。

def producer(q): ... try: q.put(item, block=False) except queue.Full: log.warning('queued item %r discarded!', item)

如果你试图让消费者线程在执行像 q.get() 这样的操作时,超时自动终止以便检查终止标志,你应该使用 q.get() 的可选参数 timeout ,如下:

_running = Truedef consumer(q): while _running: try: item = q.get(timeout=5.0) # Process item ... except queue.Empty: pass

最后,有 q.qsize() q.full() q.empty() 等实用方法可以获取一个队列的当前大小和状态。但要注意,这些方法都不是线程安全的。可能你对一个队列使用 empty() 判断出这个队列为空,但同时另外一个线程可能已经向这个队列中插入一个数据项。所以,你最好不要在你的代码中使用这些方法。

以上就是Python如何实现线程间通信的详细内容,更多关于Python 线程间通信的资料请关注真格学网其它相关文章!

Python指它的标准实现,即CPython(虽然不是很严格)本文分4个部分C/C++ 调用 Python (基础篇)— 仅讨论Python官方提供的实现方式Python 调用 C/C++ (基础篇)— 仅讨论Python官方提供的实现方式C/C++ 调用 Python (高级篇)— 使用 CythonPython 调用 C/C++ (高级篇)— 使用 SWIG练习本文中的例子,需要搭建Python扩展开发环境。具体细节见搭建Python扩展开发环境 - 蛇之魅惑 - 知乎专栏1 C/C++ 调用 Python(基础篇)Python 本身就是一个C库。你所看到的可执行体python只不过是个stub。真正的python实体在动态链接库里实现,在Windows平台上,这个文件位于 %SystemRoot%\System32\python27.dll。你也可以在自己的程序中调用Python,看起来非常容易://my_python.c #include <Python.h> int main(int argc, char *argv[]) { Py_SetProgramName(argv[0]); Py_Initialize(); PyRun_SimpleString("print 'Hello Python!'\n"); Py_Finalize(); return 0; } 在Windows平台下,打开Visual Studio命令提示符,编译命令为cl my_python.c -IC:\Python27\include C:\Python27\libs\python27.lib 在Linux下编译命令为gcc my_python.c -o my_python -I/usr/include/python2.7/ -lpython2.7 在Mac OS X 下的编译命令同上产生可执行文件后,直接运行,结果为输出Hello Python! Python库函数PyRun_SimpleString可以执行字符串形式的Python代码。虽然非常简单,但这段代码除了能用C语言动态生成一些Python代码之外,并没有什么用处。我们需要的是C语言的数据结构能够和Python交互。下面举个例子,比如说,有一天我们用Python写了一个功能特别强大的函数:def great_function(a): return a + 1 接下来要把它包装成C语言的函数。我们期待的C语言的对应函数应该是这样的:int great_function_from_python(int a) { int res; // some magic return res; } 首先,复用Python模块得做‘import’,这里也不例外。所以我们把great_function放到一个module里,比如说,这个module名字叫 great_module.py接下来就要用C来调用Python了,完整的代码如下:#include <Python.h> int great_function_from_python(int a) { int res; PyObject *pModule,*pFunc; PyObject *pArgs, *pValue; /* import */ pModule = PyImport_Import(PyString_FromString("great_module")); /* great_module.great_function */ pFunc = PyObject_GetAttrString(pModule, "great_function"); /* build args */ pArgs = PyTuple_New(1); PyTuple_SetItem(pArgs,0, PyInt_FromLong(a)); /* call */ pValue = PyObject_CallObject(pFunc, pArgs); res = PyInt_AsLong(pValue); return res; } 从上述代码可以窥见Python内部运行的方式:所有Python元素,module、function、tuple、string等等,实际上都是PyObject。C语言里操纵它们,一律使用PyObject *。Python的类型与C语言类型可以相互转换。Python类型XXX转换为C语言类型YYY要使用PyXXX_AsYYY函数;C类型YYY转换为Python类型XXX要使用PyXXX_FromYYY函数。也可以创建Python类型的变量,使用PyXXX_New可以创建类型为XXX的变量。若a是Tuple,则a[i] = b对应于 PyTuple_SetItem(a,i,b),有理由相信还有一个函数PyTuple_GetItem完成取得某一项的值。不仅Python语言很优雅,Python的库函数API也非常优雅。现在我们得到了一个C语言的函数了,可以写一个main测试它#include <Python.h> int great_function_from_python(int a); int main(int argc, char *argv[]) { Py_Initialize(); printf("%d",great_function_from_python(2)); Py_Finalize(); } 编译的方式就用本节开头使用的方法。在Linux/Mac OSX运行此示例之前,可能先需要设置环境变量:bash:export PYTHONPATH=.:$PYTHONPATH csh:setenv PYTHONPATH .:$PYTHONPATH 2 Python 调用 C/C++(基础篇)这种做法称为Python扩展。比如说,我们有一个功能强大的C函数:int great_function(int a) { return a + 1; } 期望在Python里这样使用:>>> from great_module import great_function >>> great_function(2) 3 考虑最简单的情况。我们把功能强大的函数放入C文件 great_module.c 中。#include <Python.h> int great_function(int a) { return a + 1; } static PyObject * _great_function(PyObject *self, PyObject *args) { int _a; int res; if (!PyArg_ParseTuple(args, "i", &_a)) return NULL; res = great_function(_a); return PyLong_FromLong(res); } static PyMethodDef GreateModuleMethods[] = { { "great_function", _great_function, METH_VARARGS, "" }, {NULL, NULL, 0, NULL} }; PyMODINIT_FUNC initgreat_module(void) { (void) Py_InitModule("great_module", GreateModuleMethods); } 除了功能强大的函数great_function外,这个文件中还有以下部分:包裹函数_great_function。它负责将Python的参数转化为C的参数(PyArg_ParseTuple),调用实际的great_function,并处理great_function的返回值,最终返回给Python环境。导出表GreateModuleMethods。它负责告诉Python这个模块里有哪些函数可以被Python调用。导出表的名字可以随便起,每一项有4个参数:第一个参数是提供给Python环境的函数名称,第二个参数是_great_function,即包裹函数。第三个参数的含义是参数变长,第四个参数是一个说明性的字符串。导出表总是以{NULL, NULL, 0, NULL}结束。导出函数initgreat_module。这个的名字不是任取的,是你的module名称添加前缀init。导出函数中将模块名称与导出表进行连接内容来自www.zgxue.com请勿采集。


  • 本文相关:
  • python多线程通信queue队列用法实例分析
  • python 实现线程之间的通信示例
  • python基于event实现线程间通信控制
  • python tcpserver 多线程多客户端通信的实现
  • python队列、进程间通信、线程案例
  • python 多线程中子线程和主线程相互通信方法
  • python多线程编程(八):使用event实现线程间通信
  • python复制列表时[:]和[::]之间有什么区别
  • python word转pdf代码实例
  • 为什么黑客都用python(123个黑客必备的python工具)
  • python 生成一个从0到n个数字的列表4种方法小结
  • python网络爬虫之爬取微博热搜
  • python scipy卷积运算的实现方法
  • 梅尔频率倒谱系数(mfcc)及python实现
  • win10用vscode打开anaconda环境中的python出错问题的解决
  • python中redis查看剩余过期时间及用正则通配符批量删除key的方法
  • 使用pandas对数据进行筛选和排序的实现
  • 如何实现 C/C++ 与 Python 的通信
  • 如何实现 C/C++ 与 Python 的通信
  • 线程间通信,定时向线程发送消息,C++实现
  • Qt线程间通信,如何在线程外部对线程进行控制,问题请看问题补...
  • Qt例子,线程间通信,如何在线程外部对线程进行控制,问题请看问...
  • 如何用python写个串口通信的程序
  • java 线程间通信的几种方式
  • 线程间通信有哪些方式
  • C++线程间通信都是用全局变量吗?
  • C#线程间通信问题!急急急!子线程中新建窗体问题
  • java线程间通信问题
  • java 线程间通信有几种方式
  • 关于WPF UI线程间通信和资源共享问题
  • Java线程间通信的问题
  • 大神救命啊 android线程间通信 handler message之类的
  • vs2010 C++窗体应用程序 串口 线程间通信。 我最近第一次用...
  • java多线程的同步控制与线程间的通信
  • 线程间的通信 Java
  • 如何实现VLAN间通信,有哪些方式?
  • 网站首页网页制作脚本下载服务器操作系统网站运营平面设计媒体动画电脑基础硬件教程网络安全vbsdos/bathtahtcpythonperl游戏相关vba远程脚本coldfusionruby专题autoitseraphzonepowershelllinux shellluagolangerlang其它首页python多线程通信queue队列用法实例分析python 实现线程之间的通信示例python基于event实现线程间通信控制python tcpserver 多线程多客户端通信的实现python队列、进程间通信、线程案例python 多线程中子线程和主线程相互通信方法python多线程编程(八):使用event实现线程间通信python复制列表时[:]和[::]之间有什么区别python word转pdf代码实例为什么黑客都用python(123个黑客必备的python工具)python 生成一个从0到n个数字的列表4种方法小结python网络爬虫之爬取微博热搜python scipy卷积运算的实现方法梅尔频率倒谱系数(mfcc)及python实现win10用vscode打开anaconda环境中的python出错问题的解决python中redis查看剩余过期时间及用正则通配符批量删除key的方法使用pandas对数据进行筛选和排序的实现python入门教程 超详细1小时学会python 列表(list)操作方法详解python 元组(tuple)操作详解pycharm 2020最新永久激活码(附python 字典(dictionary)操作详解pycharm 使用心得(一)安装和首python strip()函数 介绍python 中文乱码问题深入分析python中使用xlrd、xlwt操作excepython科学计算环境推荐——anacpython实现自动登录百度空间的方法python操作redis的方法python实现12306抢票及自动邮件发送提醒付numpy中loadtxt 的用法详解python continue继续循环用法总结pycham查看程序执行的时间方法python使用urllib模块的urlopen超时问题解python rsa 加密解密python 实现图像快速替换某种颜色python、matlab求定积分的实现
    免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 帮助中心 - 频道导航
    Copyright © 2017 www.zgxue.com All Rights Reserved