如何连接java 多线程 信号量中的信号与槽

初学QT,前期因为信号与槽只能在QT界面上面方便的使用,没有想到只要继承QObject便能使用且支持多线程操作。
为了能够让后台自定义类能够使用信号与槽,首先在自定义类继承QObject
1.DayouTraderSpi.h
#include &qobject.h&
class DayouTraderSpi : public QObject,public CThostFtdcTraderSpi
//宏必须申明
DayouTraderSpi(CThostFtdcTraderApi* api) :pUserApi(api){};
~DayouTraderSpi();
signals://自定义的信号
void signal_add_int(QString);
2.DayouTraderSpi.cpp
DayouTraderSpi::~DayouTraderSpi()
//析构函数必须申明
//自定义函数中触发信号void DayouTraderSpi::ReqQryTradingAccount(){
emit signal_add_int(&ok&);}
然后在界面定义槽函数及链接信号与槽
1.DayouOption.h
class DayouOption : public QMainWindow
DayouOption(QWidget *parent = 0);
~DayouOption();
private slots:
void set_lineEdit_text(QString);//自定义槽函数
2.DayouOption.cpp
DayouOption::DayouOption(QWidget *parent)
: QMainWindow(parent),
ui(new Ui::DayouOptionClass)
ui-&setupUi(this);
MdApi = CThostFtdcMdApi::CreateFtdcMdApi();
dayouMDSpi = new DayouMDSpi(MdApi);//创建回调处理类对象
TraderApi = CThostFtdcTraderApi::CreateFtdcTraderApi();
dayouTraderSpi = new DayouTraderSpi(TraderApi);
//链接信号与槽 dayouTraderSpi指针必须是QObject类型,所以dayouTraderSpi必须继承QObject。Qt::QueuedConnection是链接方式的一种。
connect(dayouTraderSpi, SIGNAL(signal_add_int(QString)), this, SLOT(set_lineEdit_text(QString)), Qt::QueuedConnection);
DayouOption::~DayouOption()
//槽函数实现void DayouOption::set_lineEdit_text(QString str)
QMessageBox::warning(this, &查询成功&, str);
传递消息的方式有四个取值:
Qt::DirectConnection&When emitted, the signal is immediately delivered to the slot. 假设当前有4个slot连接到QPushButton::clicked(bool),当按钮被按下时,QT就把这4个slot按连接的时间顺序调用一遍。显然这种方式不能跨线程(传递消息)。
Qt::QueuedConnection&When emitted, the signal is queued until the event loop is able to deliver it to the slot. 假设当前有4个slot连接到QPushButton::clicked(bool),当按钮被按下时,QT就把这个signal包装成一个 QEvent,放到消息队列里。QApplication::exec()或者线程的QThread::exec()会从消息队列里取消息,然后调用
signal关联的几个slot。这种方式既可以在线程内传递消息,也可以跨线程传递消息。
Qt::BlockingQueuedConnection&Same as QueuedConnection, except that the current thread blocks until the slot has been delivered. This connection type should only be used for receivers in a different
thread. Note that misuse of this type can lead to dead locks in your application. 与Qt::QueuedConnection类似,但是会阻塞等到关联的slot都被执行。这里出现了阻塞这个词,说明它是专门用来多线程间传递消息的。
Qt::AutoConnection&If the signal is emitted from the thread in which the receiving object lives, the slot is invoked directly, as with Qt::DirectC otherwise the signal is queued, as
with Qt::QueuedConnection. 这种连接类型根据signal和slot是否在同一个线程里自动选择Qt::DirectConnection或Qt::QueuedConnection
在线程间使用信号槽进行通信时,需要注意必须使用元数据类型
Qt内生的元数据类型,如int double QString 等
如果要用自己定义的数据类型,需要在connect前将其注册为元数据类型。形式见代码。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:14923次
排名:千里之外
转载:45篇
(19)(11)(3)(1)(6)(1)(10)主线程中发出一个信号,另一个线程槽函数没有响应,这个问题搞了好几个小时,才发现原来是connect时候的第5个参数写错了,在这里做下备注吧。
connect用于连接qt的信号和槽,在qt编程过程中不可或缺。它其实有第五个参数,只是一般使用默认值,在满足某些特殊需求的时候可能需要手动设置。
Qt::AutoConnection: 默认值,使用这个值则连接类型会在信号发送时决定。如果接收者和发送者在同一个线程,则自动使用Qt::DirectConnection类型。如果接收者和发送者不在一个线程,则自动使用Qt::QueuedConnection类型。
Qt::DirectConnection:槽函数会在信号发送的时候直接被调用,槽函数运行于信号发送者所在线程。效果看上去就像是直接在信号发送位置调用了槽函数。这个在多线程环境下比较危险,可能会造成奔溃。
Qt::QueuedConnection:槽函数在控制回到接收者所在线程的事件循环时被调用,槽函数运行于信号接收者所在线程。发送信号之后,槽函数不会立刻被调用,等到接收者的当前函数执行完,进入事件循环之后,槽函数才会被调用。多线程环境下一般用这个。
Qt::BlockingQueuedConnection:槽函数的调用时机与Qt::QueuedConnection一致,不过发送完信号后发送者所在线程会阻塞,直到槽函数运行完。接收者和发送者绝对不能在一个线程,否则程序会死锁。在多线程间需要同步的场合可能需要这个。
Qt::UniqueConnection:这个flag可以通过按位或(|)与以上四个结合在一起使用。当这个flag设置时,当某个信号和槽已经连接时,再进行重复的连接就会失败。也就是避免了重复连接。
本文已收录于以下专栏:
相关文章推荐
连接不上的问题有很多种,如信号与槽的参数不匹配,参数为自定义类型等等。今天碰到的一个问题是多线程中,信号与槽一直连接不上。防止忘记,记录一下。
这个问题的情景是一个QObject的...
最近用QT做一个服务器,众所周知,QT的主线程必须保持畅通,才能刷新UI。所以,网络通信端采用新开线程的方式。在涉及到使用子线程更新Ui上的控件时遇到了点儿麻烦。网上提供了很多同一线程不同类间采用信号...
QObject::connect: Cannot queue arguments of type 'ERROR_LEVEL'
(Make sure 'ERROR_LEVEL' is registe...
qt线程(转)----这篇很专业!
 标签:qt   [&a class=&operlink& hre
注:此文是从我的QQ空间里移出来的,因为觉的用那么多空间,blog了太累了,它发表于
日 23:22 --------------------------------------...
看到一篇好文章,特地转载下来,很详细很全面,收藏之。
原文地址:/user1/1425/archives/.html
connect用于连接qt的信号和槽,在qt编程过程中不可或缺。它其实有五个参数,只是一般使用默认值,在满足某些特殊需求的时候可能需要手动设置。
Qt::AutoConnection: 默认值,使用这...
看到一篇好文章,特地转载下来,很详细很全面,收藏之。
原文地址:/user1/1425/archives/.html
Qt的signals/slots是可以用在线程间的。由于事件循环(event loop)是在主线程完成的,所以在非主线程发送一个信号时,对应的槽函数将会由主线程执行。
熟悉多线程的读者应该都感受到...
在 Qt文档中,术语“可重入”与“线程安全”被用来说明一个函数如何用于多线程程序。假如一个类的任何 函数在此类的多个不同的实例上,可以被多个线程同时调用,那么这个类被称为是“可重入”的。假如不同的线程作用在同一个实例上仍可以正常工作,那么称之为 “线程安全”的。
大多数c++类天生就是可重入的,因为它们典型地仅仅引用成员数据。任何线程可以在类的一个实例上调用这样的成员函数,只要没有 别的线程在同一个实例上调用这个成员函数。举例来讲,下面的Counter 类是可重入的:
class Counter
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)3240人阅读
文章来源:
Qt支持三种类型的信号-槽连接:
1,直接连接,当signal发射时,slot立即调用。此slot在发射signal的那个线程中被执行(不一定是接收对象生存的那个线程)
2,队列连接,当控制权回到对象属于的那个线程的事件循环时,slot被调用。此slot在接收对象生存的那个线程中被执行
3,自动连接(缺省),假如信号发射与接收者在同一个线程中,其行为如直接连接,否则,其行为如队列连接。
连接类型可能通过以向connect()传递参数来指定。注意的是,当发送者与接收者生存在不同的线程中,而事件循环正运行于接收者的线程中,使用直接连接是不安全的。同样的道理,调用生存在不同的线程中的对象的函数也是不是安全的。QObject::connect()本身是线程安全的。
This enum describes the types of connection that can be used between signals and slots. In particular, it determines whether a particular signal is delivered to a slot immediately or queued for delivery at a later time.
Description
Qt::AutoConnection
(default) If the signal is emitted from a different thread than the receiving object, the signal is queued, behaving as Qt::QueuedConnection. Otherwise, the slot is invoked directly, behaving as Qt::DirectConnection. The type of connection is determined when
the signal is emitted.
Qt::DirectConnection
The slot is invoked immediately, when the signal is emitted.
Qt::QueuedConnection
The slot is invoked when control returns to the event loop of the receiver's thread. The slot is executed in the receiver's thread.
Qt::BlockingQueuedConnection
Same as QueuedConnection, except the current thread blocks until the slot returns. This connection type should only be used where the emitter and receiver are in different threads.&Note:&Violating this rule can cause your application to deadlock.
Qt::UniqueConnection
Same as AutoConnection, but the connection is made only if it does not duplicate an existing connection. i.e., if the same signal is already connected to the same slot for the same pair of objects, then the connection will fail. This connection type was introduced
in Qt 4.6.
Qt::AutoCompatConnection
The default type when Qt 3 support is enabled. Same as AutoConnection but will also cause warnings to be output in certain situations. See&&for further information.
With queued connections, the parameters must be of types that are known to Qt's meta-object system, because Qt needs to copy the arguments to store them in an event behind the scenes. If you try to use a queued connection and get the error message:
QObject::connect: Cannot queue arguments of type 'MyType'
Call&() to register the data type before you establish the connection.
When using signals and slots with multiple threads, see&.
See also&,&(),
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1380378次
积分:10536
积分:10536
排名:第1538名
原创:153篇
转载:265篇
评论:124条
(11)(9)(3)(9)(4)(3)(1)(2)(1)(2)(4)(1)(2)(5)(5)(31)(22)(21)(8)(20)(24)(31)(22)(19)(1)(10)(13)(34)(7)(8)(6)(8)(15)(22)(9)(23)(2)Qt 多线程中的信号/槽 - 远近闻名的学渣 - 博客园
随笔 - 102, 文章 - 1, 评论 - 4, 引用 - 0
connect函数的五个参数表示的意义依次为:sender*, signal, receiver*, slot,connectionTpye
其中槽可以是receiver的成员函数,或者是任意可访问的静态函数。在多线程的情形下:
1. 一个对象的线程就是创建该对象时的线程,而不论该对象的定义是保存在那个线程中;
  比如在thread1中开了个新线程thread2,那么thread2 对象就是定义在thread1中的,即thread2对象本身是属于thread1的,而在thread2的run函数中定义的对象则是属于thread2的。
2. QObject的connect函数有几种连接方式,
& & & a) DirectConnection,信号发送后槽函数立即执行,由sender的所在线程执行;
& & & b) QueuedConnection,信号发送后返回,相关槽函数由receiver所在的线程在返回到事件循环后执行;
& & & c) 默认使用的是Qt::AutoConnection,当sender和receiver在同一个线程内时,采用DirectConnection的方式,当sender和receiver在不同的线程时,采用QueuedConnection的方式。
所以如果发生了跨线程调用,即在线程a中使用了线程b的对象就会报各种错误,如:
Cannot create children for a parent that is in a different thread
QSocketNotifier: socket notifiers cannot be enabled from another thread
Assert failure:Cannot send events toobjects owned by a different thread
产生这个问题的原因就是因为sender跟receiver可能是属于不同的线程,可能会导致发出信号的线程与接收信号执行槽函数的线程不同。比如sender发出信号x,让槽函数处理一下某些数据,这些数据显然跟sender是在一个线程的,但执行槽函数的时候线程切换了,就等于在处理别的线程的数据了。
解决办法有:
1,采用直接连接方式,让槽函数在发出信号的对象所依赖的线程中执行,也就是不让信号进入消息队列,直接处理,但是这样貌似需要对线程同步进行处理。
2,将receiver移动至sender的线程,比如在thread1中创建了一个thread2,在thread2的run函数中创建了一个obj。想让obj发出信号,然后thread2对象来处理,那么在创建thread2之后把thread2用moveToThread(thread2)移动到thread2中即可,这样sender跟receiver就在同一个线程中了,不过拘束不推荐这么做
3,文档中推荐的方法为:在run函数中创建一个对象,这个对象肯定是属于thread2的,然后使用thread2作为revcever来处理信号即可
  1 遇见各种乱起八糟的连接问题,可以make clear把各种.o什么的删了重新编译,或者删掉自动生成的makfile,或者检查pro文件。
  3 既然线程对象本身是属于父线程的,为何在run函数中使用对象的成员不会出现跨线程- -!是说qthread对象本身就可以跨线程访问么。。不明白09:38 提问
请问Qt中两个线程之间如何用信号槽传递数据如”QByteArray“
恳请各位前辈多多指点
最好有代码实现
万分感谢!!!!
按赞数排序
你都用到线程了,还不会用信号和槽么。
比如线程A定义public slots:
public void receivedata(QByteArray data);
线程B定义signals:
public void sendData(QByteArray data):
然后connect(B,SIGNAL(sendData(QByteArray data),A,SLOT(receivedata(QByteArray data);
发射的时候直接:emit sendData(array);
其他相似问题

我要回帖

更多关于 java 多线程 信号量 的文章

 

随机推荐