|
Right, got all that. You're avoiding my questions though
Worker thread waits on the event
(Assuming the event is set within 1000ms the first time around...)
Worker thread resets event
Worker thread calls SpcSetParam
Worker thread posts the message.
UI thread gets the message, gets the data, sets the event.
Loop
Unless SpcSetParam takes alot of time, you're posting alot of events to the ui thread per second.
If SpcSetParam needs continuous input, regardless of changes to the sliders, that's one thing.
If SpcSetParam doesn't need to be called unless a slider position changes, then it would be WAY
more efficient to make it event driven - just call SpcSetParam whenever a slider changes.
Again, as it looks now, you're getting little-to-no benefit from the extra thread.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
ok, the hardware i'm using is a analog signal generator, and i monitor the signal on the oscilloscope.
the sliders are used to change the signal output.
the hardware come with its own library functions, which is the SpcSetParam().it sets the hardware to run in FIFO mode, a typical mode for continuous data output.
the SpcSetParam get the data from a software buffer, in this case, my data array contain slider positions,pass it to hardware buffer, then the data in hardware buffer is outputed and i can see it on the oscilloscope.
i want to see the output continously, it can't just run it once and gone, that's why i'm looping.
SpcGetParam() does not take long since the hardware processing speed is 100MB/s.
SpcGetParam() just take the data buffer contain the slider position, so the output doesn't reflect on immediate change of sliders, since looping is fast, the effect is almost immediate.
|
|
|
|
|
I agree with Mark, event driven is definitely the way to go.
Option 1:
declare pbyData[] as an array of volatile values
use OnHScroll & OnVScroll to update the pbyData[] values when slider positions change
Add a pointer value (assigned to pbyData) as one of the members of THREADPARMS
Then you only have to check for the kill event in your worker thread.
Only one event to monitor which is only ever set from the main thread, no deadlocks.
NOTE: Without a SwitchToThread() call in the worker thread loop, this approach will kill your interface responsiveness (& your O/S responsiveness without a multicore CPU!). If you're thinking of a Sleep(...) call, you might as well use a timer...
Option 2:
use OnHScroll & OnVScroll to update the pbyData[] values when slider positions change
Set a timer (delay value depending on exactly what you mean by "continuously output")
Call SpcGetParam() in OnTimer()
No threads, no deadlocks.
T-Mac-Oz
|
|
|
|
|
hi, T-Mac, thx for the reply. I'm not sure if you familiar with the First in,First out(FIFO) mode,the hardware use the fifo mode and the function, SpcGetParam(), i can't change it.
the ScpGetParam function just take a chunk of data in the software data buffer and store the content to onboard hardware buffer, wut if i'm trying to write data into pbyData[] in OnVScroll() while SpcGetParam() try to reads it?
the SpcGetParam() could be running at 100Hz, i really don't think using a timer is such a good idea.
the thing i'm trying to do is like changing the output anytime and the data is outputing contiunously and endlessly, and i can monitor the output on oscilloscope in real time.
i really don't have any better idea other than running a worker thread and using message to tell the main thread to store the data. if someone have any better way to do it, please do tell me
|
|
|
|
|
Hi Albert,
After having another look at your original posted code, it seems you are using threads to perform what is essentially a sequential task!
Worker thread posts WM_USER_GET_DATA
Main thread receives WM_USER_GET_DATA*
Main thread calculates output
Main thread signals "output" event
Worker thread receives "output" event
Worker thread outputs data
Worker thread posts WM_USER_GET_DATA
Main thread receives WM_USER_GET_DATA*
Main thread calculates output
Main thread signal "output" event
Worker thread receives ...
* Yes, the main thread is processing other messages but given that the WM_USER_GET_DATA is sent to the main thread using PostMessage(...), the worker thread ends up having to wait on processing of other messages before its WM_USER_GET_DATA message is processed anyway!
A much cleaner solution that accomplishes exactly the same thing is:
#define WM_USER_GET_DATA WM_USER+0x100
class CMy61xxMTDlg : public CDialog
{
.....
bool m_bDoOutput;
afx_msg LRESULT OnGetData(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnUserStop(WPARAM wParam, LPARAM lParam);
DECLARE_MESSAGE_MAP()
.....
void OnUserGetData();
void OnBnClickedButtonStart()
{
m_bDoOutput = true;
PostMessage(WM_USER_GET_DATA);
};
void OnBnClickedButtonStop() { m_bDoOutput = false; };
.....
}
......
BEGIN_MESSAGE_MAP(CMy61xxMTDlg, CDialog)
......
ON_MESSAGE (WM_USER_GET_DATA, OnUserGetData)
......
END_MESSAGE_MAP()
void CMy61xxMTDlg::OnUserGetData()
{
if (!m_bDoOutput)
return;
ptr8 pbyData;
for (i=0; i<BUFSIZE; i ++)
{
pbyData[i]=(int8)m_Slider_Data[i].GetPos();
}
SpcSetParam(...);
PostMessage(WM_USER_GET_DATA);
}
Threads are great for their intended purpose, which is to permit semi-independent operations to execute in parallel.
The tight looping and total dependence on event signals should have tipped me off right away that what you were trying to achieve was not really parallel processing at all.
As you've already found out, threads and thread synchronisation are tricky beasts, so it's always worth exploring alternative implementations (such as timers and/or user message events) before resorting to a multi-threaded solution to a problem.
Threading sounds cool & it is cool but don't leap into trying to use threads just because you think you can, you will most often come up with a sub-optimal solution.
BTW. I do understand the FIFO concept & that is precisely why using a timer is a better idea than continually looping in a background thread (or perhaps even the self-propagating event solution above).
If, as you say, SpcGetParam(...) adds the supplied data in the on-board hardware buffer (i.e. the end of the FIFO queue), then a system running at 2Gz (forget FSB, the small volume of data we're talking about here can almost be guaranteed to always be cached), with the other minimal processing involved, feeding a FIFO queue being read at 100MHz will sooner or later (probably sooner) fill & overflow (or maybe wrap around, or block, or drop values, depends on the firmware) the hardware buffer. Using a timer gives you the opportunity to match your output frequency to the oscilloscope frequency. If the standard system timer resolution is not fine-grained enough for you, there are other timers available in windows, search Code Project for "timers" & you'll find plenty of articles. If you insist on using threads, protecting access to m_pbyData[] as a member of CMy61xxMTDlg is easily accomplished using mutexes.
Regards,
T-Mac-Oz
|
|
|
|
|
It's very hard to differentiate between your code snippets and the actual text. Please revise your post by surrounding the code snippets with <pre> tags. Then, before committing the post, preview it to make sure everything is as you expect it to be (e.g., angle brackets).
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
How do I go about displaying JPG/GIF images?
Simon Smith
|
|
|
|
|
One way is to read the file and convert to a device independent bitmap or a device dependent bitmap
and use GDI to render the image.
GDI+ can do the loading and drawing for you in a few simple steps.
ATL has the CImage class which will do it as well.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Thank you for your responce
I am very new to visual c++, so I dont know what the gdi+
or the ATL is
What I am trying to do is to try out some imaging processing, so i'll need it in the raw form.
I belive visual has the facility to get the pixel attributes
Is it possible to load the image to the screen and get
the approbiate values from this kind of method?
Thanks very much
Simon Smith
simon smith
|
|
|
|
|
I would say the CImage class would be an easy place to start and be able to work with images right away.
Before I try putting some sample code here -
Are you using MFC or straight Win32?
Do you have basic Windows programming skills as far as windowing, messages, etc?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I am learning visuall c++ again, I learnt it about 8 years
ago from a book from wrox.
so some stuff makes sense, but I am going through the book again.
I am useing mfc and I have basic progframing skills
(loops, ifs, pointers)
regarding windows programing skills, Once I have gone through the book again, I can then only tell you how I am
at it.
Can you recommend any books or websites that I can further
develop my skills.
If you have any source code suitable for me regarding the imaging or anything that would be great
from my understanding so far, I have created a single document mfc application. Do I add theb Cimage class the same as the virtual functions?
cheers Simon
the virtual functions, this is an area I am stuck on
simon
|
|
|
|
|
Hi simon,
I wizarded together an SDI application that loads tiff/bmp/jpeg/gif files as a CImage.
I'll email it to you.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Simple way is:
#include "AtlImage.h"
CImage m_Image;
m_Image.Load("c:\\yourfile.jpg");
e.BitBlt(dc->m_hdc,800,600);
m_Image.Detach();
|
|
|
|
|
Do you have any sample code that demonstrates this,
I am a begginer and I'm not sure how this fits in
|
|
|
|
|
I have the exact image of a .bmp file in memory, loaded from a database. How can I create a valid CBitmap from it and get it to print?
I can load the .bmp file locally using LoadImage(...LR_LOADFROMFILE...), which returns a valid HBITMAP handle, and it prints fine. But when I use CreateBitmap() et al. and try to load the instance with the in-memory bitmap info from BITMAPFILEHEADER and BITMAPINFOHEADER (width, height, planes etc.) it fails when I try to SelectObject() into a temporary DC.
How can I duplicate all of the functions of LoadImage() when the source is neither a resource nor an actual file, but rather an image of the .bmp file in memory? The goal is to end up with a valid HBITMAP handle that can then be Selected into a DC and printed.
Does anyone have any code examples for this kind of operation?
Thanks.
|
|
|
|
|
You could use CreateDIBSection() to create the HBITMAP then copy the pixel bits to the
DIB section.
BITMAPFILEHEADER *pBitmapFileHeader = (BITMAPFILEHEADER*)pFileBytesInMemory;
BITMAPINFO *pBitmapInfo = (BITMAPINFO*)((BYTE*)pFileBytesInMemory + sizeof(BITMAPFILEHEADER));
BYTE *pBitmapBits = 0;
HBITMAP hBitmap = ::CreateDIBSection(NULL, pBitmapInfo, DIB_RGB_COLORS, &pBitmapBits, NULL, 0);
if (hBitmap)
{
memcpy(pBitmapBits, (BYTE*)pFileBytesInMemory + pBitmapFileHeader->bfOffBits, pBitmapInfo->bmiHeader.biSizeImage);
...
}
Mark
.
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Mark,
Thank you, thank you, thank you! It worked beautifully the first time.
I wish the documentation was easier to plod through to find simple solutions like this so I wouldn't have to waste two days and then have to ask anyway.
Thanks again.
Bion
|
|
|
|
|
You're welcome!
bions wrote: I wish the documentation was easier to plod through to find simple solutions like this so I wouldn't have to waste two days and then have to ask anyway.
We all do
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I need some quick help and i thought of the guru's on this forum. My cd/dvd rom won't read or write to Blank CD's. It reads Blank DVD's but says the file system is raw and has 0 bytes on the blank 4gb dvd.
I've tried to uninstall the cdrom and then searched for added hardware, but still nothing. what can i do?
|
|
|
|
|
You may want to try posting this on the Hardware board.
That's my quick help
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
But why did it take you three minutes to provide said help? Come on, Mark, that's not the philosophy around here.
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
I'm getting slow in my old age
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
hi everybody
how can i send data in mysql data base through mfc dialog based application.
i am new for mfc and mysql please guide me with some code and example
I will be more obliged .
regard
malik
|
|
|
|
|
rajneshmalik wrote: please guide me with some code and example
You are in luck. CodeProject is all about guides and example code. There is a massive amount of Database related articles here. Now all you need to do is look around the CodeProject Web Site, locate the list of articles and start working! To do that there are what is called "links" on these pages that you can "read" and then "click on" to navigate around the site. GOOD LUCK!
|
|
|
|
|
Hi,
Is it possible to write an dll, which can be accessed both from exe and webpage(using ASP)?
Regards,
John.
|
|
|
|
|