--
You received this message because you are subscribed to a topic in the Google Groups "fltk.general" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/fltkgeneral/-bIjXnLQCL4/unsubscribe?hl=en-US.
To unsubscribe from this group and all its topics, send an email to fltkgeneral...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
--
You received this message because you are subscribed to a topic in the Google Groups "fltk.general" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/fltkgeneral/-bIjXnLQCL4/unsubscribe?hl=en-US.
To unsubscribe from this group and all its topics, send an email to fltkgeneral+unsubscribe@googlegroups.com.
--
You received this message because you are subscribed to a topic in the Google Groups "fltk.general" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/fltkgeneral/-bIjXnLQCL4/unsubscribe?hl=en-US.
To unsubscribe from this group and all its topics, send an email to fltkgeneral...@googlegroups.com.
I changed the custom colors to hex constants, i.e., for example,as suggested and ran a simulation. It worked! I will test in the car soon. Thanks!
const Fl_Color my_fl_gray = (Fl_Color)0x80808000;
// COLOR MAP INDEX color(0x000000II) ------ | | | | Color map index (8 bits) Must be zero
button->color(0x000000ff); // colormap index #255 (FL_WHITE)
or specify a color using a hex constant for the RGB components:
// RGB COLOR ASSIGNMENTS color(0xRRGGBB00) | | | | | | | Must be zero | | Blue (8 bits) | Green (8 bits) Red (8 bits)
--
he said that Fl::lock() and unlock() pair is still needed for the widget->value() call. Is it still true for the Fl_Gauge class which overloads the value() method? I am attaching a set of files that can be compiled with either Cygwin or MinGW just for testing the drawing and updating. Inside the Fl_Gauge.cxx file you can see that the value() function does nothing but change a bunch of Fl_Gauge class variables such as Value and TextColor, except inside myredraw() function there is a call to redraw() that is surrounded by Fl::lock() and unlock() pair. In other words the Fl_Gauge::value() function stores the value in a separately defined class variable Value, and does not rely on the original Fl widget value() function to store the value. (The program needs to run from the command line with an argument either 0 or 1 to tell it to call redraw() from the main thread without locking or from the worker thread with locking.) So in this case do I still need to surround the overloaded value() method with Fl::lock() and unlock() pair? Thanks!
Short answer; it depends. (Threads is hard...)
If you are accessing the GUI context, then you need the locks. Though here, as we have said before, I would *not* “conceal” the locks in the class methods, I would make them explicit in the calling context.
If you are *not* accessing the GUI context, then you may not need the locks, if you don’t mind the code being a bit hacky.
If you are simply writing class member data that will be read by the other thread “later”, then it may (in practice) work fine to do that without locking.
Conceptually, the threads are fully asynchronous, so the reader can read whilst the writer is writing. In which case the reader will likely get the wrong value, every now and then. Or indeed the writer value might be marked invalid by the cache coherency logic even though it was just written. Weird stuff happens.
Then you need to decide:
- Does the occasional bad-read matter? If the display is refreshing “often”, displaying one bad value every now and then might not even be visible to the user. Do you care?
- If your system only has a single CPU, that is simulating multi-threading by multi-tasking, then there is no actual simultaneous access in practice, so code will often work fine on a single-core CPU (then behave really weirdly on a modern multi-core CPU!)
- If you have a single writer, and one or more readers, you can *often* get away with this with no locking; the writer value will *probably* be written atomically when the cache line is flushed to ensure cache-coherency. (Most current multi-core systems have cache-snooping in h/w to ensure cache coherency across CPU cores.)
- If you have multiple writers, you probably do need locks to allow the writers to arbitrate access to the store. Two threads writing to the same location will *not* go well.
BUT these do not need to be fltk locks, since you are not accessing the GUI context. So you can create your own mutex just to protect the access to the member variables. Using this mutex will be much cheaper and faster than locking the flk context, since it will not need to pause until the GUI context is available; it can usually acquire the mutex straight away.
- Similarly, if you are worried about your reader getting duff values, you should use a non-fltk lock (i.e. a mutex) to protect the data. This will allow you to ensure that “good” values are written, and read, without having to delay for the GUI context to synchronize. So it is cheap to do.
By the way the Cygwin graphics looks a lot smoother than the MinGW version. The latter has many visible jagged edges in curves. Also the MinGW display update seems jumpier. Is there a way to measure how frequent the re-drawing of a widget is actually executed? Thanks!
Greg’s already posted some suggestions, so you get the idea; basically, subclass your draw method, count how many times it is called, and every now and then, check the elapsed time and work out the average frame rate...
--
--
You received this message because you are subscribed to a topic in the Google Groups "fltk.general" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/fltkgeneral/-bIjXnLQCL4/unsubscribe.
Conceptually, the threads are fully asynchronous, so the reader can read whilst the writer is writing. In which case the reader will likely get the wrong value, every now and then. Or indeed the writer value might be marked invalid by the cache coherency logic even though it was just written. Weird stuff happens.
Then you need to decide:
- Does the occasional bad-read matter? If the display is refreshing “often”, displaying one bad value every now and then might not even be visible to the user. Do you care?
- If your system only has a single CPU, that is simulating multi-threading by multi-tasking, then there is no actual simultaneous access in practice, so code will often work fine on a single-core CPU (then behave really weirdly on a modern multi-core CPU!)
- If you have a single writer, and one or more readers, you can *often* get away with this with no locking; the writer value will *probably* be written atomically when the cache line is flushed to ensure cache-coherency. (Most current multi-core systems have cache-snooping in h/w to ensure cache coherency across CPU cores.)
- If you have multiple writers, you probably do need locks to allow the writers to arbitrate access to the store. Two threads writing to the same location will *not* go well.
BUT these do not need to be fltk locks, since you are not accessing the GUI context. So you can create your own mutex just to protect the access to the member variables. Using this mutex will be much cheaper and faster than locking the flk context, since it will not need to pause until the GUI context is available; it can usually acquire the mutex straight away.
- Similarly, if you are worried about your reader getting duff values, you should use a non-fltk lock (i.e. a mutex) to protect the data. This will allow you to ensure that “good” values are written, and read, without having to delay for the GUI context to synchronize. So it is cheap to do.
class BankAccount { boost::mutex mtx_; int balance_; public: void Deposit(int amount) { mtx_.lock(); balance_ += amount; mtx_.unlock(); } void Withdraw(int amount) { mtx_.lock(); balance_ -= amount; mtx_.unlock(); } int GetBalance() { mtx_.lock(); int b = balance_; mtx_.unlock(); return balance_; } };
Regarding Ian's earlier comment:
What's the read value when a bad read happens? Say the writer writes 3.2, then 5.6, and then 4.8. Does a bad read mean that the reader reads back something like 3.2, 3.2, 4.8 which just misses some values and/or having some values delayed/duplicated. Or is it like this 3.2, 65535.34875, 4.8 which has completely corrupted wrong data?
Is there a way to tell the system to run the program with only one CPU core?
Yes I only have one worker thread (writer) and one main thread (reader).
I am leaning toward using a mutex to be on the safe side if it's not too complicated. Unfortunately I have been using Boost::thread and the examples I found is clear but no detailed explanation.
--
You received this message because you are subscribed to a topic in the Google Groups "fltk.general" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/fltkgeneral/-bIjXnLQCL4/unsubscribe.
--
You received this message because you are subscribed to a topic in the Google Groups "fltk.general" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/fltkgeneral/-bIjXnLQCL4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to fltkgeneral+unsubscribe@googlegroups.com.
Albrecht
--
You received this message because you are subscribed to a topic in the Google Groups "fltk.general" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/fltkgeneral/-bIjXnLQCL4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to fltkgeneral...@googlegroups.com.
I really like the approach but am having some difficulty. I narrowed down the problem in the function setUIstate() below. It is called by the callback function for the Go/Stop button that starts/stops a simulation or actual data collection. A worker thread is started in the case Running. In the case Stopped, I would like to wait for the worker thread to end before re-activating the button. But the program hangs right at the workerThread.join() statement.
--
You received this message because you are subscribed to a topic in the Google Groups "fltk.general" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/fltkgeneral/-bIjXnLQCL4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to fltkgeneral+unsubscribe@googlegroups.com.
--
You received this message because you are subscribed to a topic in the Google Groups "fltk.general" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/fltkgeneral/-bIjXnLQCL4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to fltkgeneral...@googlegroups.com.