| Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date | |
| All threads index page 4 | |
Qt! How to transfer a lot of data from one QObject to another that live in a different thread? The setup is quite like the mandelbrot example, but with the important difference that the data should not be copied when transfering. (In the mandelbrot the QImage object is transfered embedded in queued signals, which means it is copied) But here, the data that is to be transfered should not be copied! I want a mechanism like queued signals, saying that the data is ready for read at a given pointer address, for example. But this means having a global buffer object. Right? Is it not a bad idea having a global object? And in this particular example how would one organize and protected the global buffer? With QSemaphore? Merry Christmas!! Frank -- [ signature omitted ]
Frank wrote: > How to transfer a lot of data from one QObject to another that live in a > different thread? > Why not emit a QByteArray by reference in a Qt::QueuedConnection? Does the receiving side need to write to it? --Dave -- [ signature omitted ]
Dave Smith wrote: > > Why not emit a QByteArray by reference in a Qt::QueuedConnection? Does > the receiving side need to write to it? > No, it does not need to write to it. So maybe that works. What about deletion time of the QByteArray? Assuming the signals are queued: Can the emmiting object delete the QByteArray right after emmiting it? Or does the receiving object has to take care of the deletion? Does Qt delete the object when the last reference to it is being deleted?? Frank -- [ signature omitted ]
Frank wrote: > No, it does not need to write to it. So maybe that works. > Great! > What about deletion time of the QByteArray? Assuming the signals are queued: > Can the emmiting object delete the QByteArray right after emmiting it? Or > does the receiving object has to take care of the deletion? > If you are using Qt::BlockingQueuedConnection (new in Qt 4.3 or so), then you can just wait until all the receivers are done (by virtue of the fact that your "emit" returned), and then clean it up in the emitter. If you can't use Qt::BlockingQueuedConnections, someone else will have to be responsible for cleaning it up, perhaps a reaper thread or some form of GC. > Does Qt delete the object when the last reference to it is being deleted?? > Beacuse QByteArray does not inherit QObject, Qt does not track it at all, and does not clean it up for you in any way. --Dave -- [ signature omitted ]
Dave Smith wrote:
> Frank wrote:
>
>> Does Qt delete the object when the last reference to it is being
>> deleted??
>>
>
> Beacuse QByteArray does not inherit QObject, Qt does not track it at
> all, and does not clean it up for you in any way.
>
What about writing a class for the transfers which inherits QObject and
implements its destructor? Like:
class PassInSignal : public QObject
{
public:
~PassInSignal() { delete data };
PassInSignal(QByteArray & ba) { data = new QByteArray(ba) };
private:
QByteArray * data;
}
Creating an object of this class will not copy the data. If this is used in
the signal, is it possible to use non blocking queued signals and delete
the object right after emmiting it??
I bother because I've got the feeling that using blocking signals is not a
choice.
Frank
--
[ signature omitted ]
Frank wrote:
> What about writing a class for the transfers which inherits QObject and
> implements its destructor? Like:
>
> class PassInSignal : public QObject
> {
> public:
> ~PassInSignal() { delete data };
> PassInSignal(QByteArray & ba) { data = new QByteArray(ba) };
> private:
> QByteArray * data;
> }
>
> Creating an object of this class will not copy the data. If this is used in
> the signal, is it possible to use non blocking queued signals and delete
> the object right after emmiting it??
>
Qt will not delete that object for you either, even though it inherits
QObject. It only auto-deletes QObjects that are children of other
QObjects, and only when the parent QObject is deleted. In other words,
you would still have to manage deleting it yourself.
--Dave
--
[ signature omitted ]
Frank wrote: >Dave Smith wrote: >> Why not emit a QByteArray by reference in a Qt::QueuedConnection? Does >> the receiving side need to write to it? > >No, it does not need to write to it. So maybe that works. > >What about deletion time of the QByteArray? Assuming the signals are > queued: Can the emmiting object delete the QByteArray right after > emmiting it? Or does the receiving object has to take care of the > deletion? > >Does Qt delete the object when the last reference to it is being > deleted?? Why do you have a QByteArray* in the first place? Just pass it by const-reference or by value and it'll do the right thing. QByteArray is one of the tool classes: reentrant, atomically ref-counted, implicitly shared. -- [ signature omitted ]
Attachment:
signature.asc
Description: This is a digitally signed message part.
Thiago Macieira wrote: > > Why do you have a QByteArray* in the first place? > > Just pass it by const-reference or by value and it'll do the right thing. > > QByteArray is one of the tool classes: reentrant, atomically ref-counted, > implicitly shared. > Just to be sure: You refer to a const reference to a "QByteArray" or a call-by-value with a "QByteArray", right? Using QByteArray with call-by-value in a signal will not copy the data until the receiving side writes to the copy it gets. Is this true?? Is this the feature of being implicitly shared?? Furthermore: Does the feature of being ref-counted enable the emmiting side to delete the QByteArray right after emmiting it?? Frank -- [ signature omitted ]
Frank wrote: > Using QByteArray with call-by-value in a signal will not copy the data until > the receiving side writes to the copy it gets. Is this true?? Is this the > feature of being implicitly shared?? > It's supposed to, but in my experience with QString (which supposedly does the same thing), it is much faster to pass by reference than by value, especially when dealing with large strings. My results led me to believe, in fact, that the implicit sharing feature in QString doesn't actually save you much. > Furthermore: Does the feature of being ref-counted enable the emmiting side > to delete the QByteArray right after emmiting it?? You don't have to delete anything if you're not dealing with pointers. --Dave -- [ signature omitted ]
Dave Smith wrote: >It's supposed to, but in my experience with QString (which supposedly >does the same thing), it is much faster to pass by reference than by >value, especially when dealing with large strings. My results led me to >believe, in fact, that the implicit sharing feature in QString doesn't >actually save you much. There is a speed impact, that's true, between passing by const-reference and passing by value. But the impact is O(1) -- it does not matter what size your string is. When you pass by value, there's an atomic increment that is done and a new object is created on the stack (or on the registers, depending on your architecture). The atomic increment can take several clock cycles to complete (I don't know how many). When you pass by const-reference, all it does is pass a pointer value around. That's extremely fast. That's why you see everywhere in Qt code QStrings being passed as: const QString &. Note, however, that some classes shouldn't be passed by reference, but instead by value. QLatin1String would be one of them -- but we dropped the ball when we made it. For Qt 5, we shall rectify that. -- [ signature omitted ]
Attachment:
signature.asc
Description: This is a digitally signed message part.
Thiago Macieira wrote: > There is a speed impact, that's true, between passing by const-reference > and passing by value. But the impact is O(1) -- it does not matter what > size your string is. > That's not what my experience suggests. I have a bunch of code that passes QStrings by value over lost of signals/slots (all Qt::DirectConnections), and it works fast for small strings. As soon as large strings (like 10's of MB in size) are passed, the whole thing slows down considerably. I changed the signal/slot parameters to be pass-by-const-reference instead of pass-by-value, and didn't change anything else, and things went back to normal speed. --Dave -- [ signature omitted ]
Dave Smith wrote: >Thiago Macieira wrote: >> There is a speed impact, that's true, between passing by >> const-reference and passing by value. But the impact is O(1) -- it >> does not matter what size your string is. > >That's not what my experience suggests. I have a bunch of code that >passes QStrings by value over lost of signals/slots (all >Qt::DirectConnections), and it works fast for small strings. As soon as >large strings (like 10's of MB in size) are passed, the whole thing >slows down considerably. I changed the signal/slot parameters to be >pass-by-const-reference instead of pass-by-value, and didn't change >anything else, and things went back to normal speed. Well, I am telling you the size of the string has no impact in the adding-one-ref performance. (The default copy constructor or the assignment operator). If you can show us the code and some performance measurements data, we can probably rectify the issue. My (very, very) early guess is that you called a non-const method in your function, which made the QString detach and, therefore, copy the data. -- [ signature omitted ]
Attachment:
signature.asc
Description: This is a digitally signed message part.
Frank wrote:
>Thiago Macieira wrote:
>> Why do you have a QByteArray* in the first place?
>>
>> Just pass it by const-reference or by value and it'll do the right
>> thing.
>>
>> QByteArray is one of the tool classes: reentrant, atomically
>> ref-counted, implicitly shared.
>
>Just to be sure: You refer to a const reference to a "QByteArray" or a
>call-by-value with a "QByteArray", right?
>
>Using QByteArray with call-by-value in a signal will not copy the data
> until the receiving side writes to the copy it gets. Is this true?? Is
> this the feature of being implicitly shared??
Implicitly-shared = copy on write. If you have a QByteArray that was
passed by value, it will not copy the data until you modify the object.
It shares with other instances of the same data (hence "shared") and
automatically detaches from them when you make a modification
(hence "implicitly").
>Furthermore: Does the feature of being ref-counted enable the emmiting
> side to delete the QByteArray right after emmiting it??
Don't say "delete" because it'll lead you to think of
delete byteArray;
That's not it. We are NOT talking about QByteArray*.
But you can let the QByteArray object go out of scope. As in:
{
QByteArray byteArray = ....;
emit signal(byteArray);
}
--
[ signature omitted ]
Attachment:
signature.asc
Description: This is a digitally signed message part.