The possibility of MFC multithreaded compilation

Source: Internet
Author: User

1, the reason is "possible", because there is a point is that the temporary object is the encapsulation of the HWND operation, not the window class encapsulation. Thus all hwnd temporary objects are instances of CWnd, even if the above forcibly converted to cabcdialog* is still cwnd*, so when Cabcdialog::assertvalid is called in Assert_valid, it defines some additional checks, It may be found that this is an instance of CWnd rather than an Cabcdialog instance, resulting in an assertion failure. Therefore, all cabcdialog should be replaced with CWnd, although the failure continues, but still wrong (not to mention pdialog->m_data how to do), because the temporary object is the HWND operation of the encapsulation, Unfortunately, UpdateData is just an operation of the dialog data exchange mechanism (DDX) provided by MFC itself, not by sending messages to the HWND, but by virtual function mechanisms. So the dodataexchange that invokes the instance in UpdateData will not be able to call Cabcdialog::D Odataexchange, but instead call CWnd::D Odataexchange, so nothing will happen.

So a reasonable (and not necessarily the best) solution is to send a message to an instance of Cabcdialog, and pass the data through an intermediate variable (such as a global variable) instead of using Cabcdialog::m_data. Of course, if the data is small, such as this example, the data should be passed as message parameters, reduce the complexity of the code, the data should be passed through global variables, reduce the cost of buffering management. The following changes are followed:
#define AM_DATANOTIFY (Wm_user + 1)
static DWORD g_data = 0;
DWORD WINAPI threadproc (void *pdata)//thread function (for example, to get data from a COM port)
{
Data acquisition Loops
The data is obtained and placed in the variable i
G_data = i;
CWnd *pwnd = cwnd::fromhandle (reinterpret_cast< HWND > (pData));
Assert_valid (PWND); This example should call the platform SendMessage instead of the wrapper class, here is just a demo
Pwnd->sendmessage (am_datanotify, 0, 0);
...
}
Begin_message_map (Cabcdialog, CDialog)
...
On_message (am_datanotify, ondatanotify)
...
End_message_map ()
BOOL Cabcdialog::oninitdialog ()
{
CDialog::OnInitDialog ();
Other initialization code
CreateThread (null, 0, ThreadProc, m_hwnd, 0, NULL); Creating Threads
return TRUE;
}
LRESULT cabcdialog::ondatanotify (WPARAM/* WPARAM *, LPARAM//LPARAM */)
{
UpdateData (FALSE);
return 0;
}
void Cabcdialog::D odataexchange (CDataExchange *pdx)
{
CDialog::D odataexchange (PDX);
DDX_Text (PDX, idc_edit1, G_data);
}

2. Precautions
What is the concept of "thread safety"?
I used to listen to the master to warn MFC objects not to use across threads, because MFC is not thread-safe. For example, CWnd objects are not used across threads and can be replaced with window handles (HWND). The Csocket/casyncsocket object should not be used across threads, instead of using the socket handle. So what is thread safety? When to think about it? If the program involves multithreading, you should consider thread safety. For example, if you design an interface that needs to be used in a multithreaded environment in the future, or if you need to use an object across threads, this must be considered. There is no authoritative definition of thread safety. Here I just say my understanding: The provided interface is atomic to the thread or the switch between multiple threads does not result in ambiguity in the execution of the interface, that is, we do not have to consider the problem of synchronization.
Generally, "thread safety" is caused by multi-threaded access to shared resources. Such an interface is not thread-safe if it is necessary for us to take synchronous measures to protect the shared resources accessed by the interface when invoking an interface. Both MFC and STL are not thread-safe. How can I design a class or interface for thread safety? If the data that is accessed in the interface is private, the interface is thread-safe. Or if several interfaces are read-only for shared data, then such interfaces are thread-safe. If there are shared data between multiple interfaces, and if there is read and write, If the designer has taken the synchronization measures, the caller does not need to consider the data synchronization problem, the interface is thread-safe, otherwise it is not thread-safe.

3, multi-threaded program design should pay attention to what?
1, minimize the use of global variables, static variables to do shared data, as far as possible to use parameters to pass objects. The object passed by the parameter should include only the required member variables. The so-called required member variables are bound to be multithreaded operations. Many people take the trouble to pass the this pointer (which may be any object pointer) as a thread parameter, causing the thread to have too many permissions to manipulate the parameters in this. The whole program is done by one person, may be very careful, not wrong, but as long as a transfer, the program will be beyond recognition. When two threads manipulate a member variable at the same time, the program begins to crash, and, worse, the error is difficult to reproduce. (I am depressed this problem, we are a few people, the program into the debug version, after several days of use, only to find errors.) Finding the error is only the beginning, because it is also very difficult to prove that the bug was modified successfully. In fact, the inter-threading data interaction is mostly unidirectional, the thread callback function at the entrance, as far as possible to back up the incoming data into the local variables (of course, the variables used for inter-thread communication can not be handled so), only the local variables are processed, can be a good solution to this problem.
2, in MFC, please use the thread carefully. Because the framework of MFC assumes that your message processing is done in the main thread. The first window handle belongs to the thread, and if the thread that owns the window handle exits, the problem occurs if another thread handles the window handle. and MFC in order to avoid this situation, so that you call the message (window) processing function in the child thread, will be constantly out of the assert error, bored to death you. The typical example is CSocket, because CSocket uses a hidden window to implement false blocking, so it is unavoidable to use a message handler, and if you use CSocket in a child thread, you may see the Assert pop-up.
3. Do not register COM components in different threads at the same time. Two threads, one registered 1.ocx, 2.ocx, 3.ocx, 4.ocx; While the other registered 5.ocx, 6.ocx, 7.ocx, 8.ocx, the results of deadlock occurred, respectively, died in FreeLibrary and DllRegisterServer, because the 8 OCX is done in MFC, it may be MFC bug, But DllRegisterServer died in GetModuleFileName, and GetModuleFileName is an API alas! If there is a passer-by to see, happen to know the reason, please do not hesitate to enlighten.
4, do not make the thread so complicated. Many beginners, hate can not use all the functions of the thread related, here mutually exclusive, there wait, a thread, a while off the thread, than the goto statement. Good multi-threaded program, should be as little as possible to use the thread. This sentence how to understand, that is, as far as possible to unify a data sharing area to hold data queues, working sub-threads from the queue to take data, processing, and then put back data, so that it will be modular, object-based, and not every data is a working sub-thread processing, the process is closed, while writing a direct, etc.

The possibility of MFC multithreaded compilation

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.