|
You could create an array of 8 threads 0..7, iterate in a loop and have the threads read a line each.
Remember to lock the critical section when a thread accesses line.
While (count<10)
{
myThread[threadCount].readLineInto(myLineArray[count]);
threadCount++;if(threadCount>7) threadCount=0;
count++;
}
CCriticalSection cs;
cs.Lock();
cs.Unlock();
....
cs.Lock();
cs.Unlock();
Synchronized multi-threading in C++ (No MFC!)
Synchronized multi-threading in C++ (No MFC!)
class MyThread : public Thread {
private:
int m_nCount;
public:
MyThread(int n,const char* nm) {
Thread::setName(nm);
m_nCount = n;
}
void run() {
for(int i=0;i<m_nCount;i++) {
cout << getName().c_str() << ":" << i << endl;
}
}
};
int main() {
Thread *t1 = new MyThread(15,"Thread 01");
Thread *t2 = new MyThread(10,"Thread 02");
try {
t1->start();
t2->start();
t1->stop();
t2->stop();
}catch(ThreadException ex) {
printf("%s\n",ex.getMessage().c_str());
}
delete t1;
delete t2;
return 0;
|
|
|
|
|
csrss wrote: So how can i implement this? How to check if some line has been already read by some thread and another thread will not read it again?
Critical Section and a User defined DataStructure is needed here
"Opinions are neither right nor wrong. I cannot change your opinion. I can, however, change what influences your opinion." - David Crow Never mind - my own stupidity is the source of every "problem" - Mixture
cheers,
Alok Gupta
VC Forum Q&A :- I/ IV
Support CRY- Child Relief and You
|
|
|
|
|
I'm sorry, but that's a VERY crude example to learn multi-threading. Please do some reading on this subject (there are plenty of good books). Here's a fantastic link: http://www.flounder.com/workerthreads.htm[^] to begin with.
“Follow your bliss.” – Joseph Campbell
|
|
|
|
|
Bah ... ugly!
A file is a randomly accessible sequence of bytes, not "lines", since "lines" cannot be defined independently each other.
To give each thread a line to read, you must know where each line begins, and to know that you've to read all the preceding lines. At that point your "read" will be in any case sequential.
If you want to play this kind of game, try with a more structured file, containing "units" of fixed length.
---
Ah ... an opened file have just one "position", so it cannot be read simultaneously from different places. You need to open it more times (so that you can have independent "positions"), in read-sharing mode.
2 bugs found.
> recompile ...
65534 bugs found.
|
|
|
|
|
Never, never access the same data between the threads.
Follow the small set of simple rules of threading.
The rules:
Rule #1: Do not access the same data between the threads.
Rule #2: Do not pass references or pointers to variables between threads.
Rule #3: Use windows messages to interact with the GUI.
#1 Do not access the same data between the threads.
The code passes the dialog's this pointer to the thread, but accessing isn't thread safe.
#2 Do not pass references or pointers to variables.
The code passes a pointer to the local ThreadParam variable.
If OnSomeButton goes out of scope before MyThreadProc tries to access the parameter
things will of course go bad.
Allocate with new and let the thread delete it when finished.
#3 Use windows messages to interact with the GUI.
|
|
|
|
|
Sorry for the late answer but ...
I've heard of the "rules" you're talking about relatively to MFC, because of its internal structure(and may relate to Wx having a similar structure), but the OP has never mentioned MFC.
If you work with HANDLE (for either files and threads) none of those rules necessarily applies.
Threads accessing same data are normal (and that's what synchronization objects like mutex or criticalsection are for ...)
2 bugs found.
> recompile ...
65534 bugs found.
|
|
|
|
|
How could I route all the windows messages of a dialog to a thread with their parameters?
|
|
|
|
|
|
Your Dialog messages will probably be filtered by you main message loop. Instead of letting the system handle these, you could:
1) Filter them yourself, and pass them as structured messages to your thread through some shared object, before letting the default handlers loose.
2) filter them yourself, and send them to a control in your in your other thread, again before letting the default handlers loose.
|
|
|
|
|
Thank you, But would you mind post a sample code or at least a link of some examples
regards
|
|
|
|
|
Are you using a framework (like MFC), or is this plain C/C++ ? i.e. who controls the message loop?
You'll find some plain examples here[^] (not exactly you problem, but close enough). In general, Raymond Chen's blog contains lots of interesting articles on message handling in Windows. ( After all, he wrote the bloody thing). You'll find that, if you're doing this in MFC, MFC only provides a thin layer on top of the standard functions, so it should be easy to reproduce the examples in MFC.
|
|
|
|
|
Yes I am using MFC, just a sample code or help may solve my problem
|
|
|
|
|
The API functions ::PostMessage and ::SendMessage are thread safe!
That means you can use the windows handle (ie the CWnd::m_hWn d) to interact with your MFC classes.
#define MYMESS_CALL_SOME_METHOD (WM_APP + 1)
struct ThreadParam
{
HWND mDlg;
};
UINT MyThreadProc( LPVOID pParam )
{
ThreadParam* p = static_cast<ThreadParam*> (pParam);
::SendMessage(p->mDlg, MYMESS_CALL_SOME_METHOD, 0, 0);
delete p;
}
void CMyDialog::OnSomeButton()
{
ThreadParam* param = new ThreadParam;
param->mDlg = m_hWnd;
AfxBeginThread(MyThreadProc, param);
param = 0;
}
Declare a method in the dialog message map (in the .h file)
...
afx_msg LRESULT OnCallSomeMethod(WPARAM, LPARAM);
DECLARE_MESSAGE_MAP()
Map the message to the method and implement the method (in the .cpp file):
BEGIN_MESSAGE_MAP(CMyDialog, CDialog)
...
ON_MESSAGE(MYMESS_CALL_SOME_METHOD, OnCallSomeMethod)
END_MESSAGE_MAP()
LRESULT CMyDialog::OnCallSomeMethod(WPARAM wp, LPARAM lp)
{
callSomeMethod();
return 0;
}
|
|
|
|
|
Michael Jansson wrote: ::SendMessage are thread safe!
Hi Michael,
Could you explain why SendMessage is thread-safe?
Best Wishes,
-David Delaune
|
|
|
|
|
SendMessage is thread-safe because can be called from multiple threads
without unwanted interaction between the threads.
MFC is not thread safe. Use the windows handle CWnd::m_hWnd to interact with MFC classes
and SendMessage and PostMessage to dispatch messages.
|
|
|
|
|
Michael Jansson wrote: SendMessage is thread-safe because can be called from multiple threads
without unwanted interaction between the threads
You mean such as deadlocking due to a blocking call?
Michael Jansson wrote: MFC is not thread safe.
SendMessage[^] is not thread-safe. The function will generally not return until the called function has returned a LRESULT. If the function being called hangs... SendMessage will never return. Using SendMessage between threads is a recipe for disaster.
Best Wishes,
-David Delaune
|
|
|
|
|
|
Thanks the article helped me alot
|
|
|
|
|
I recently started using a Logitech keyboard with several specific special keys - volume control, WWW, E-Mail, Mute, and so on, and they all work. So I'm wondering what it sends when I press them.
The keyboard did not require any special software - just plug it in and go. So I reason that the only thing it can send are keyboard keystrokes, since its a keyboard without host software.
I reason further that if I knew what it sends then I should be able to send the same thing by striking keys on the keyboard. In other words, regardless of what application is running, I should be able to send a sequence of keystrokes that will open up my e-mail client. Am I right?
Does anyone have an idea what's going on here?
Thanks folks..
glyfyx
|
|
|
|
|
I'm pretty sure there are key codes reserved for those special functions.
For instance, the code 198 (just an example) might tell Windows to open the default mail client.
Another tells it to open the default browser.
So it doesn't send key combinations, just certain key codes.
|
|
|
|
|
glyfyx wrote: Does anyone have an idea what's going on here?
I do. You want to read this[^]. It's quite old, but the info is still current. Note that this only documents the standard keyboard device driver, used if you don't install any logitech drivers.
If you install the logitech drivers, the Logitech driver enables a lot more scan codes, and unfortunately, I have the impression that it also switches a number of these standard scan codes.
|
|
|
|
|
Thanks - especially for the link that explains the mystery.
Glyfyx
|
|
|
|
|
Im in the CMainFrame class. I have a CFormView with many screens. In
CMainFrame, how can I get a pointer to my class so that I can access
variables in the CFormView. I have:
<br />
CListCtrl* CMainFrame::GetListCtrl1098()<br />
{<br />
CMyFormView *pView = NULL;<br />
<br />
CListCtrl* pmyListCtrl = &pView->m_list_1098;<br />
<br />
return pmyListCtrl;<br />
}<br />
But *pView is null and I get an error. How can I make
*pView attain access to its class and hence variables?
Please, any response any one can give me will be greatly appreciated.
Sincerely,
Danielle Brina (an overworked graduate student)
|
|
|
|
|
You could try pView = GetActiveView();
You may be right
I may be crazy
-- Billy Joel --
Within you lies the power for good - Use it!
|
|
|
|
|
The problem is, GetActiveView() returns something other than the
CMyFormView which has the listctrl that I want to attain.
Even if I try:
<br />
void CMainFrame::GetListCtrl()<br />
{<br />
CMyFormView *pView;<br />
<br />
CListCtrl* pmyListCtrl = NULL;<br />
<br />
if (pView)<br />
{<br />
AfxMessageBox("view active");<br />
<br />
pmyListCtrl = pView->m_list_ctrl;<br />
<br />
int total = pmyListCtrl->GetItemCount();<br />
<br />
CString s;<br />
s.Format("total = %i", total);<br />
AfxMessageBox(s);<br />
}<br />
}<br />
it doesnt work.
Please any response any one can give me will be greatly appreciated.
Sincerely,
Danielle Brina (an overworked graduate student)
|
|
|
|