From: Daniel J S. <dan...@ie...> - 2014-02-14 04:30:39
|
On 02/13/2014 05:09 AM, Yuriy Kaminskiy wrote: > sfeam wrote: >> On Wednesday, 12 February 2014 08:50:18 PM Daniel J Sebald wrote: >>> On 02/12/2014 02:49 PM, Thomas Bleher wrote: >>>> * Daniel J Sebald<dan...@ie...> [2014-02-12 06:36]: >>>>> In any case, I suggest adding the sleep as Ethan has done. There is >>>>> no reason that should be running at 100%. In fact, there is >>>>> probably a preferred way to do this without polling loops. I >>>>> learned a little bit about Qt working on Octave and Qt has this >>>>> paradigm of signals and slots and the developers suggest adhering to >>>>> the concept otherwise can get kind of dodgy (not in this simple >>>>> case...but cases where widget IDs are floating about). >>>>> >>>>> signal: something that a Qt object emits >>>>> slot: the destination of the signal which can >>>>> be of any number, e.g., five other >>>>> objects could connect a slot to a signal >>>>> >>>>> Anyhow, I don't have time to look at this right now, but if one >>>>> looks at the documentation for a Qt socket: >>>>> >>>>> http://qt-project.org/doc/qt-4.8/qlocalsocket.html#connectToServer >>>>> >>>>> it indicates that a signal is emitted when the connection is >>>>> complete and there is a signal emitted when there is an error. So >>>>> the proper thing to do is to first make connections to the socket >>>>> sort of like the following ("success" and "failed" are custom member >>>>> functions): >>>>> >>>>> connect (createdsocket, SIGNAL (connected ()), watcher, SLOT (success ())); >>>>> connect (createdsocket, SIGNAL (error ()), watcher, SLOT (failed ())); >>>>> >>>>> and then tell the socket to attempt to connect to the server: >>>>> >>>>> createdsocket->connectToServer (name) >>>>> >>>>> There is no need to check in a loop for anything. Either the socket >>>>> will successfully connect and emit "connected" at which point >>>>> "success()" will get called or the socket will timeout and emit >>>>> "error" at which point "failed()" will get called. >>>>> >>>>> One can get very creative about connections made, the number of >>>>> slots watching a signal, doing this dynamically, etc. So instead of >>>>> a recursive routine, it might be multiple connections, or >>>>> dynamically reconnect/disconnect in the "failed()" slot. Etc. >>>> signals and slots are indeed very nice, but they need a Qt event loop to >>>> work correctly. I don't think it is possible to add the Qt event loop to >>>> gnuplot without major surgery. (Well, you can start a local event loop >>>> using QEventLoop inside a function, but in this case it's just more work >>>> to get the same result we already have). >>> Good point, but we'll see if we can make it work somehow. It's worth at >>> least a couple hours time to test whether it is feasible. It would seem >>> that the place to start the Qt event loop along with setting up initial >>> signals/slots would be upon calling "term qt". The good thing is that >>> the graphics is done in the satellite Qt program. The bits accessible >>> to gnuplot core don't need graphics, so perhaps that Qt event loop could >>> be run in a different, non-main thread without too much work. >>> >>> Local event loop might work, but that seems like a lot of overhead to >>> communicate every time with a remote program with any sort of high >>> bandwidth. Local event loops are what dialog boxes can and often use. >>> Overhead isn't an issue there. >> >> I don't agree that an event loop is needed for this particular purpose. >> We don't have a case of asynchronous processes sending each other >> signals at random times. We just want some way for the daughter >> process to signal back to the parent process "I'm ready now, you can >> proceed". And we want some way for the parent to wait for this >> signal without burning CPU cycles. One would think from its name that >> QLocalSocket::waitForConnected() provides exactly this service, but >> evidently it doesn't. At least in linux it should be possible to have the >> parent call sigwait(), and the daughter call kill(parent_pid, SIGUSR1). >> No need to involve Qt in this. > > Signals is *increadibly* fragile IPC mechanism. There are very hard restriction > on what is permitted in signal handlers (that frequently violated, which result > in very hard-to-catch and nasty bugs), you can easily end up with racy code, > signals may lost, etc. I've not experienced such a thing and found, so far, Qt signals/slots fairly robust. Mutexes seem to work rather well for across thread traffic. Do you have an example of a race condition? I can't think of any hard and fast rules other than one isn't supposed to cast the object ID and use it as an object pointer because the object could be deleted. (Emitted signals are fine because any time an object is deleted, all its connections are removed along with it.) Within a thread there shouldn't be a race condition because signals are processed right away, if I remember correctly. Across thread are treated differently. They are queued. But there is where the Mutex comes into play. By temporarily suspending a worker process (typically on the order of milliseconds) and having the thread awoken when tasks are complete, race conditions are avoided. Dan |