这篇文章有个大概的比较和说明:
http://blog.chinaunix.net/uid-20754930-id-1877623.html
GUI主循环设计及其在MiniGUI, GTK, QT的实现
以下是我针对Qt5代码(2015.4)的一个研究。
QApplication::exec
QGuiApplication::exec
QCoreApplication::exec
QEventLoop::exec
QEventLoop::processEvents
QEventDispatcher::processEvents
再以下就和具体的平台相关了。
Windows平台:
QEventDispatcherWin32::processEvents
它的实现主要是GetMessage+WaitForMultipleObjects,如上文中对MiniGUI的主循环所述。
Unix平台:
QEventDispatcherUNIX::processEvents
QEventDispatcherUNIXPrivate::doSelect
这个函数主要使用select系统调用来监听事件源。
Android平台:
QAndroidEventDispatcher::processEvents
QUnixEventDispatcherQPA::processEvents
QEventDispatcherUNIX::processEvents
以下和Unix平台相同。
近日在研究OpenGL多线程处理时,偶然看到了如下代码:
http://download.csdn.net/detail/zhoukuanbin/7669187
没有CSDN账号的读者,也可以在这里下载:
https://github.com/antkillerfarm/antkillerfarm_crazy/tree/master/Qt/MyGlTest
粗看代码,发现并无特殊的OpenGL处理,理论上应该无法达到一个线程处理渲染,另一个线程处理贴图的目标。但实际编译运行代码,又确实可用。因此这里面一定有什么原因。
void ThreadGl::run()
{
connect(this, SIGNAL(SigCopy()), this, SLOT(Copy()));
printf("ID 0:%x\n", currentThreadId());
while(1)
{
if(!m_bEndFlag)
{
break;
}
usleep(16000);
emit SigCopy();
}
qDebug("Copy End\n");
}
void ThreadGl::Copy()
{
m_glWidgets -> OnTimeOut(m_pImage, m_Formal, m_pthId);
}
这段代码引起了我的注意。粗一看,connect函数连接的SIGNAL和SLOT都属于同一个对象。而connect函数的第5个参数(这是个有默认值的可省略参数)的默认值为Qt::AutoConnection。
这是Qt官方对Qt::AutoConnection的解释:
按照字面上的意思,既然SIGNAL和SLOT都属于同一个对象,那么这里的Qt::AutoConnection就等同于Qt::DirectConnection。而Qt::DirectConnection与直接调用SLOT函数是一个效果。
于是这里将emit SigCopy();
替换为Copy();
,结果程序运行出错。
再试一下,将connect函数的第5个参数设为Qt::DirectConnection,同样有问题。
而如果将之设为Qt::QueuedConnection的话,程序运行一切正常。
综上,Qt在这里的处理,显然认为SIGNAL和SLOT属于不同的线程。
那么判断的依据是什么呢?
这里有必要对emit SigCopy();
中emit
背后的戏法做一个剖析。
众所周知,emit并非C++关键字,而属于Qt扩展的一部分。Qt为了处理这些扩展,引入了moc工具作为预处理工具。
而moc处理之后,emit SigCopy();
就变成了QMetaObject::activate
QMetaObject::activate
中使用以下代码,判定信号接收者的线程是否和信号发送者的一致。
const bool receiverInSameThread = currentThreadId == receiver->d_func()->threadData->threadId;
于是问题转化为receiver->d_func()->threadData
是怎么来的呢?
答案在QObject::QObject
中:
d->threadData = (parent && !parent->thread()) ? parent->d_func()->threadData : QThreadData::current();
从这里可以看出所谓信号接收者的线程,实际上是接收者对象创建时所处的线程。
回到原来的问题。ThreadGl虽然是Qt的线程对象,但它本身却是在主线程中创建的,所以以它为接收者,实际上就是以主线程为接收者。
显然这个例子代码并没有真正实现OpenGL多线程处理,所有的OpenGL操作实际上都是在主线程完成的。
参考:
https://blog.csdn.net/feiyangqingyun/
一个Qt的blog
PyQt是一个python语言的Qt封装。除此之外,还有一个叫PySide的库也是干这个的。
它们的区别在于:PyQt是Riverbank Computing开发的,历史早,功能强。PySide是Qt官方提供的,然而很久以来都比不过前者。。。
https://mp.weixin.qq.com/s/jNa4JTefasFDWoGJDBL6-Q
PyQt编写GUI界面
https://mp.weixin.qq.com/s/sR1R2DRA2XASx9LJExasfA
15个开源示例手把手带你用PyQt做小型桌面应用
https://zhuanlan.zhihu.com/p/35081519
Qt模拟Linux终端Terminal与系统交互(QProcess)
WebService经过近二十年的发展,已经有非常多的框架了。知名的有:Axis1、Axis2、Xfire、CXF、JWS等。
其中的JWS在JDK 1.6之后被集成到JDK中,成为了我学习的首选。
JWS包含了JAX-WS、JAX-RS、JAXB、JAXR、SAAJ、StAX等组件。这里主要涉及的是JAX-WS。
参考:
http://www.blogjava.net/zjhiphop/archive/2009/04/29/webservice.html
java调用webservice的各种方法总结
http://blog.csdn.net/lifetragedy/article/details/7205832
5天学会jaxws-webservice编程
以上两篇是中文blog。
http://java.globinch.com/enterprise-java/web-services/jax-ws/java-jax-ws-tutorial-develop-web-services-clients-consumers/
这个教程虽然是英文的,但质量超过前两篇。且该网站还有其他相关文章,质量也颇高。
本文相关的demo参见:
https://github.com/him-bhar/jax-ws
这个demo包括jaxws-demo、jaxws-demo-client-stubs和jaxws-demo-client三个模块。
使用这个demo会有若干问题,也可直接采用本人修改之后的代码:
https://github.com/antkillerfarm/antkillerfarm_crazy/tree/master/java/jax-ws
JAX-WS 2.0有两种开发过程:自顶向下和自底向上。自顶向下方式指通过一个WSDL文件来创建Web Service,自底向上是从Java类出发创建Web Service。
demo选用Server端通过Java Class生成webservice,而客户端通过wsdl生成Java调用类的做法。
这种方法的优点在于:
1.服务端开发基于Java,基本不需要对WSDL有过多研究,上手简单。
2.客户端通过wsdl生成Java调用类,可以很方便的导入第三方WebService,同样无需对WSDL有过多研究。
综上,这实际上是个由服务端驱动的开发模型。
jaxws-demo包含了两个WebService例子分别是rpc_type和document_type。
这两种类型实际上指的是SOAP Binding的类型。两者的区别参见:
http://java.globinch.com/enterprise-java/web-services/soap-binding-document-rpc-style-web-services-difference/
吐槽一下,虽然这只是个基本的问题,然而中文blog中竟然没有令人满意的文章。
这些文章的毛病在于:
1.对Java和JWS过于细节,而忽视了交互报文。SOAP Binding类型主要是个通讯协议问题,而不是Java或者JWS的问题。
2.没有比较交互报文,就来笼统的谈各自的优缺点的,都是耍流氓。
从上文的交互报文可以看出,document_type虽然更复杂,但也更灵活。从直观来看,前者只有wsdl一个文件,而后者有wsdl和xsd两个文件。
jaxws-demo编译之后,除了生成相应的.class之外,还会生成对应的wsdl和xsd文件。
通常的做法是将这些文件一起部署到诸如Tomcat之类的Web容器中。
但JDK也提供了更简易的做法,使用javax.xml.ws.Endpoint类的publish方法,将WebService绑定到特定的URI上。
这里我们将com.himanshu.poc.jaxws.service.deploy.EndpointPublisherDocument设为主类,并执行程序。
在浏览器上输入:
http://localhost:9999/ws/hellodocument?wsdl
正常情况下会返回一个wsdl文件。
JDK中,有两个和WebService相关的工具:
JAXWS为我们提供了两个工具:
wsgen。主要用于Server端通过Java类编译成Webservice及相关的wsdl文件。
wsimport。主要用于Client端(调用端)通过wsdl编译出调用Server端的Java文件。
jaxws-demo中,调用wsgen生成的wsdl和xsd文件,在这里被wsimport编译成客户端的桩代码。
由于我使用的JDK是JDK 1.8,因此会遇到如下问题:
由于 accessExternalSchema属性设置的限制而不允许 'file' 访问, 因此无法读取方案文档'xjc.xsd'。
解决方法:
<plugin>
<groupId>org.jvnet.jax-ws-commons</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>2.3</version>
<configuration>
<!-- Needed with JAXP 1.5 -->
<vmArgs>
<vmArg>-Djavax.xml.accessExternalSchema=all</vmArg>
</vmArgs>
</configuration>
</plugin>
这个问题是由于JDK 1.8以后相关权限变得更加严格所导致的。
参见:
https://my.oschina.net/fuckmylife0/blog/325432
jaxws-demo-client就是具体的客户端实现了,可以看出相比于上一步的桩代码,这里的代码文件,数量上要少得多。
正向代理,“它代理的是客户端,代客户端发出请求”。
反向代理,“它代理的是服务端,代服务端接收请求”。
http://blog.csdn.net/gzh0222/article/details/8540604
lvs、haproxy、nginx负载均衡的比较分析
https://mp.weixin.qq.com/s/SO1ZLSPaRkk8WwUl9u-JPA
仅需这一篇,吃透“负载均衡”妥妥的
https://mp.weixin.qq.com/s/3KZ99d94yqRDxEByn7nGWg
QPS比Nginx提升60%,阿里Tengine负载均衡算法揭秘
https://mp.weixin.qq.com/s/XsyXkaOIJ3m8sdCt8Pl5Ig
计算密集型服务的负载均衡策略
https://mp.weixin.qq.com/s/SmpUPJRK0TMdA0rkb_Q6VQ
什么是集群?什么又是负载均衡?
https://mp.weixin.qq.com/s/sCGI3XPga5gTZF0iskJlMA
全网最详尽的负载均衡原理图解
https://mp.weixin.qq.com/s/o5lTN4IpHmZqLUKoJsSyKw
爱奇艺TFServing负载均衡问题研究及改进实践
https://mp.weixin.qq.com/s/31DGDYpDHcYg-4qM4OczxA
深入浅出Nginx
https://mp.weixin.qq.com/s/h9sXZc4Y62f4KOSVXAB1Pg
Nginx基本功能极速入门
https://www.cnblogs.com/wcwnina/p/8728391.html
Nginx相关介绍
https://mp.weixin.qq.com/s/aCAuJQEB2pmL92OTEb_4Xg
Nginx为什么这么快?
https://mp.weixin.qq.com/s/3GSuB1tLe-G5hZPUiAXuVA
Nginx,为什么依旧这么“香”?
https://blog.csdn.net/yujing1314/article/details/107000737
搞懂Nginx一篇文章就够了
https://mp.weixin.qq.com/s/-8Ka8nMYpH7cipzfm36utw
写给小白的Nginx文章
https://mp.weixin.qq.com/s/gd59U50tlJPa4B4avXRG1Q
Nginx架构浅析
https://mp.weixin.qq.com/s/eUindWNZiCv_tSLQeYfmLg
Nginx常用配置清单
https://mp.weixin.qq.com/s/LmtHTOVOvdcnMBuxv7a9_A
Nginx最全操作总结
您的打赏,是对我的鼓励