to jiangsheng: 我想实现的其实是一个触发事件功能, 例如,文件下载完毕, 通知父线程处理数据, 并且再分配任务个这个子线程! 我说的这些,有什么好办法?
//用一个脉冲式的event吧。 这个东东没有用过!!!:(
CEvent::PulseEvent BOOL PulseEvent( );Return ValueNonzero if the function was successful; otherwise 0.ResSets the state of the event to signaled (available), releases any waiting threads, and resets it to nonsignaled (unavailable) automatically. If the event is manual, all waiting threads are released, the event is set to nonsignaled, and PulseEvent returns. If the event is automatic, a single thread is released, the event is set to nonsignaled, and PulseEvent returns. If no threads are waiting, or no threads can be released immediately, PulseEvent sets the state of the event to nonsignaled and returns.
Res The thread to which the message is posted must have created a message queue, or else the call to PostThreadMessage fails. Use one of the following methods to handle this situation: Call PostThreadMessage. If it fails, call theSleep function and call PostThreadMessage again. Repeat until PostThreadMessage succeeds. Create an event object, then create the thread. Use theWaitForSingleObject function to wait for the event to be set to the signaled state before calling PostThreadMessage. In the thread to which the message will be posted, call PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE) to force the system to create the message queue. Set the event, to indicate that the thread is ready to receive posted messages. The thread to which the message is posted retrieves the message by calling the GetMessage or PeekMessage function. The hwnd member of the returned MSG structure is NULL.
我是这样想的:
每个父线程执行一个task,
子线程则实现task的多线程下载(是一个网络应用)。
还有别的方法实现这样的功能吗?
有一点类似netants,
有多个任务,每个任务5个线程。
使用 ::PostThreadMessage(m_ThreadID,WM_MYMESSAGE,0,0);
也不行:(
多线程通信用PostThreadMessage行不行,你们是怎么实现的呢?
有别的好办法吗?
有多个任务,每个任务5个线程。
用全局变量能行吗?
我想实现的其实是一个触发事件功能,
例如,文件下载完毕,
通知父线程处理数据,
并且再分配任务个这个子线程!
我说的这些,有什么好办法?
这个东东没有用过!!!:(
BOOL PulseEvent( );Return ValueNonzero if the function was successful; otherwise 0.ResSets the state of the event to signaled (available), releases any waiting threads, and resets it to nonsignaled (unavailable) automatically. If the event is manual, all waiting threads are released, the event is set to nonsignaled, and PulseEvent returns. If the event is automatic, a single thread is released, the event is set to nonsignaled, and PulseEvent returns. If no threads are waiting, or no threads can be released immediately, PulseEvent sets the state of the event to nonsignaled and returns.
有什么特性?
一个thread是waiting状态,
我调用n_pThread->Download(url),
合法么?线程能继续运行么?
m_pThread 是CWinThread派生类。
你调用线程的成员函数,还是在当前线程中运行这个代码啊
可以用waitforsingleobject等待一个事件。
//你调用线程的成员函数,还是在当前线程中运行这个代码啊
//可以用waitforsingleobject等待一个事件。
这倒是一个问题,我没注意,
以前只写过两三个线程的程序,
现在要写线程是任意的程序,遇到了一堆的问题啊!
能送我 qq号吗?
我对vc不熟,不太了解你们说的...等东西
看看消息是否收到
如果有,你为什麽不用POSTMESSAGE(HWND,MESDSAGE,0,0)呢???
保存一个线程的ID,然后PostThreadMessage,很简单的逻辑,不会有错的。
我的工作线程都是无窗口的,属于控制台线程。所以我怀疑:
你的消息映射可能不对,你试一下在你的主线程中主动:
while (GetMessage(&msg, NULL, 0, 0))
{
LPARAM lParam = msg.lParam;
。
我的接受线称没有窗体,哪来的HWND阿。zhengyun_ustc(^-^):
可能是我的线称协调有问题
我回去看一看,我其实是想实现时间触发的效果。
我打算用CEvent试试。
进一步的问题,等我试过在向大家报告!
{
// TODO: Add your specialized code here and/or call the base class
return CWinThread::PreTranslateMessage(pMsg);
}
在这里看看消息是否真的没有收到
m_pThreadR1 = AfxBeginThread(WatchCommR1, this);
m_pThreadR1->SetThreadPriorityREAD_PRIORITY_NORMAL);
m_pThreadR1->ResumeThread();
以下几行在线程中发送消息
CView* pView = (CView*)lpParam;//lpParam在是线程的参数,即CView类的指针,(线程是在
//CView类中创建的)
(CWnd *)(pView)->PostMessage(WM_DISPLAYCOMMSTATUS, AEI1, COMM_NODATA);
//COMP1、COMM_NODATA是自定义的常数,由消息处理函数处理
//WM_DISPLAYCOMMSTATUS 是自定义消息//以下是消息处理函数
//在CView类头文件中加入以下一行
afx_msg void OnDisplayCommStatus(WPARAM wParam, LPARAM lParam);
BEGIN_MESSAGE_MAP(CCpsView, CFormView)
//{{AFX_MSG_MAP(CCpsView)
ON_WM_SIZE()
ON_WM_SHOWWINDOW()
ON_COMMAND(ID_SETTIME, OnToolSettime)
ON_WM_TIMER()
ON_COMMAND(ID_SETUP, OnSetup)
ON_CBN_DROPDOWN(IDC_COMBOCHECI, OnDropdownCombocheci)
ON_CBN_CLOSEUP(IDC_COMBOCHECI, OnCloseupCombocheci)
ON_CBN_SELCHANGE(IDC_COMBOCHECI, OnSelchangeCombocheci)
ON_BN_CLICKED(IDC_BUTTONWBQLS, OnButtonwbqls)
ON_BN_CLICKED(IDC_BUTTONXCLS, OnButtonxcls)
ON_BN_CLICKED(IDC_BUTTONYBQLS, OnButtonybqls)
ON_CBN_SELCHANGE(IDC_COMBODAY, OnSelchangeComboday)
ON_CBN_SELCHANGE(IDC_COMBOMONTH, OnSelchangeCombomonth)
ON_CBN_SELCHANGE(IDC_COMBOTGDD, OnSelchangeCombotgdd)
ON_CBN_SELCHANGE(IDC_COMBOYEAR, OnSelchangeComboyear)
ON_WM_PAINT()
ON_COMMAND(ID_CLEARALARM, OnClearalarm)
ON_COMMAND(ID_REPRINT, OnReprint)
ON_COMMAND(ID_SEARCH, OnSearch)
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CFormView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CFormView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CFormView::OnFilePrintPreview)//在消息映射表中加入以下一行
ON_MESSAGE(WM_DISPLAYCOMMSTATUS, OnDisplayCommStatus)
ON_MESSAGE(WM_COMMNOTIFY, OnCommNotify)
END_MESSAGE_MAP()//编写消息处理函数
void CView::OnDisplayCommStatus(WPARAM wParam, LPARAM lParam)
{//其中wParam 是COMP,lParam是COMM_NODATA
MSG msg;
CStatusBar* ps=(CStatusBar *)AfxGetApp()->m_pMainWnd->GetDescendantWindow(AFX_IDW_STATUS_BAR);
while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
AfxGetApp()->PumpMessage();
switch(lParam)
{
case COMM_OK:
sCommStatus = "通讯正常";
break;
case COMM_NODATA:
sCommStatus = "没有数据";
break;
case COMM_NOTCONNECTED:
sCommStatus = "未连接";
break;
case COMM_SETCONNECTERROR:
sCommStatus = "建立连接失败";
break;
case COMM_PARITYERROR:
sCommStatus = "校验错误";
break;
case COMM_ERROR:
sCommStatus = "通讯异常";
break;
default :
sCommStatus = "通讯状态未知";
break; }
(ps->GetStatusBarCtrl()).SetText(sCommStatus, wParam -1, 0);
return ;
}
http://www.csdn.net/expert/Topic/249/249613.shtm
2.自己实现同步。
The thread to which the message is posted must have created a message queue, or else the call to PostThreadMessage fails. Use one of the following methods to handle this situation: Call PostThreadMessage. If it fails, call theSleep function and call PostThreadMessage again. Repeat until PostThreadMessage succeeds.
Create an event object, then create the thread. Use theWaitForSingleObject function to wait for the event to be set to the signaled state before calling PostThreadMessage. In the thread to which the message will be posted, call PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE) to force the system to create the message queue. Set the event, to indicate that the thread is ready to receive posted messages.
The thread to which the message is posted retrieves the message by calling the GetMessage or PeekMessage function. The hwnd member of the returned MSG structure is NULL.
http://www.csdn.net/expert/Topic/249/249613.shtm
看看我的思想是不是有问题阿,
网友给我的代码也贴在那里,不过我不知我的实现有什么问题?
各位费心了!!!
thread是没有消息循环泵的,如果要传递消息,请用CWinThread,
CWinThread可以接受消息循环。
搞定....
BOOL PostThreadMessage(
DWORD idThread, // thread identifier
UINT Msg, // message to post
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);创建子线程时把父线程的idThread传给子线程就可以了。
zhyzhy(懒虫)和Mubin_Du(Mubin)合起来就是答案
jack_fu() 和lwglucky(黑客。。呵呵~~~) 错了
赫赫
每个线程都拥有系统分配的私有的内存控件,所有的动态分配内存方法所分配的内存都属于线程私有的内存,你的线程对象一定是动态分配的,所以当你在子线程中使用所有父线程的变量时,就会出现内存问题,这也就是你出现“.........Access Vidation in MFC42D.DLL.....“的原因--MFC使用了父线程的指针指向子线程中不存在的地址。之间传送父线称窗口的HANDLE或父线程的ThreadID然后使用HANDLE或ThreadID在两个线程之间进行通讯。线程最主要的两个麻烦就是同步与内存共享的问题(这也就是多线程程序编写的难点):
线程的同步问题是最讨厌的,Window与Unix/Linux相比更是缺乏工具,主要是通过时间、消息、临界区等在各线程之间驱动,跟踪多线程程序也非常困难。还有一个就是内存共享问题:
上面遇到的就是内存问题,m_parent是属于父线程的,与其它线程共享。但是,最普通的可以使用内存映射文件实现多线程程序间共享数据,但这样速度较慢。使用dll共享内存不够灵活。幸好,Windows提供了一种多线程程序间共向内存的方法,线程局部存储(TLS),具体的实现可以在Charies Petzold的著作《Windows 程序设计》(ISBN 7-301-04187-X/TP.463)中找到。
你的讲解还真是详尽阿!受益匪浅!
至于你说的TLS,我还是第一次听说。
好多介绍多线程通信的书都没有提阿!
我回去好好看看!
这么说、通过message传送的变量地址也不行了?