多个线程如何访问同一个控件

fengge8ylf 2003-05-20 08:31:19
多个线程如何访问同一个控件,比如,每次开辟60个线程,往一个控件写入数据,等这60个线程结束,再开辟60个线程也往这个控件写数据。代码如下,当开辟的线程总共超过950个时程序便处于“死机状态”了。不知为什么

CCriticalSection Section;
volatile int iCounter=0;

UINT threadA(LPVOID pParam)
{
CxxxDlg *threada=(CxxxDlg*)pParam;
Section.Lock();
int IpPort = iCounter;

iCounter++;
::PostMessage(threada->GetSafeHwnd(),WM_USER_RECALC_DONE,IpPort,0);
Section.Unlock();
return 0;

}
void CxxxDlg::OnButton1()
{
// TODO: Add your control notification handler code here
m_list.ResetContent();


GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE);
UpdateData(TRUE);
int v;
if(m_Eport == m_Sport)//m_Eport m_Sport 都是int类型,例如//m_Sport=0,m_Eport=950;
v = 1;
else
{
v = (m_Eport-m_Sport)/60;
if( ( (m_Eport-m_Sport)%60 ) > 0 )
v++;
}
HANDLE hThread[61];
CWinThread *pT[61];
iCounter = m_Sport;
//创建线程
for(int i=0;i<v;i++){
int a=0;
for(int k=0;k<60;k++)
{
a++;
if(iCounter>=m_Eport)
break;
pT[k]=AfxBeginThread(threadA,this);

hThread[k]=pT[k]->m_hThread;
}
WaitForMultipleObjects(a,hThread,TRUE,INFINITE);
}
GetDlgItem(IDC_BUTTON1)->EnableWindow(TRUE);

}
LRESULT CxxxDlg::OnRecalcDone(WPARAM wParam, LPARAM lParam)
{
int a=(int)wParam;
char bb[10];
memset(bb,0,10);
itoa(a,bb,10);
m_list.AddString(bb);
return 0;

}
把PostMessage换成SendMessage()总共开辟两三个线程程序便处于死机状态,比如m_Sport=0,m_Eport=3;不知为什么
...全文
124 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
tryber 2003-05-21
  • 打赏
  • 举报
回复
"开辟的线程数大于1000",我不知道你指的线程数是什么,从这代码来看
for(int k=0;k<60;k++)
{
if(iCounter>=950)
break;
pT[k]=NULL;
hThread[k]=NULL;

pT[k]=AfxBeginThread(Athread,(LPVOID)GetSafeHwnd());
if(pT[k]!=NULL)
{
a++;
hThread[k]=pT[k]->m_hThread;
}
}
WaitForMultipleObjects(a,hThread,TRUE,INFINITE); //nobig60
这会让程式任何时刻所有的线程数不会超过60个,行nobig60会等到这a个线程都退出后才启动下a个,但是每次这a个线程都往目标窗口发一个消息后退出,以致于你点按钮后,目标窗口要响应那么多次(发送的消息数大于1000),要加1000个item,如果有sort风格还要排序,更新视图...当然慢了.我不知你做的是什么,要是我的话,我会边启动线程边处理消息,比如让等待动作放在消息处理函数中,这样才真正达到多线程的目的.如果你非要这么做的话,建议在启动线程前用对CListBox实行InitStorage(..),一定对程序的性能大有提高,详见msdn.
fengge8ylf 2003-05-21
  • 打赏
  • 举报
回复
其实,我想提高程序速度,比如说总共要开辟120个线程,每个线程都执行不同的代码(通过iCounter可以看出)先开辟60个线程,先让这60个线程运行,运行完毕,再开辟下60个,这种方法是不是比开辟完一个线程,此线程运行完毕再开辟下一个线程的方法速度快?

上面说的“开辟的线程数大于1000”是指总的线程数。
fengge8ylf 2003-05-20
  • 打赏
  • 举报
回复
谢谢tryber(cyber) 我明白了
第一个问题“当开辟的线程总共超过950个时程序便处于“死机状态”了”应该怎么解决
tryber 2003-05-20
  • 打赏
  • 举报
回复
因为SendMessage是同程的,要等到主线程响应后才返回,但你的主线程看来是没法响应了,一直在WaitForMultipleObjects(a,hThread,TRUE,INFINITE);就这代码,你就只起动一个线程,只要线程中有SendMessage程序会死锁.
fengge8ylf 2003-05-20
  • 打赏
  • 举报
回复
tryber(cyber)不知道你的测试程序有没有往控件写数据这一步骤。如果有这个步骤的话当开辟的线程数大于1000时(for(int i=0;i<15;i++))程序长时间处于死机状态,然后提示系统资源不足。可能是有些资源没释放掉,但哪些资源没释放掉我就不知道了。当去掉PostMessage((HWND)lparam,WM_USER+10,0,0);这一句时(不往控件写数据)程序运行正常。
你的操作系统是不是2000的或XP 我的是98的
sker99 2003-05-20
  • 打赏
  • 举报
回复
多线程编程的原理是什么?
tryber 2003-05-20
  • 打赏
  • 举报
回复
我也不知为什么,而我用你的代码在我的机器上工作的好好的,尽管有点改动,但很明显你的a++这么放较合理.

CCriticalSection Section;
volatile int iCounter=0;
UINT Athread(LPVOID lparam)
{
Section.Lock();
int IpPort = iCounter;
iCounter++;
PostMessage((HWND)lparam,WM_USER+10,0,0);
Section.Unlock();
return 0;
}
void CMainFrame::OnStart()
{
// TODO: 在此添加命令处理程序代码
HANDLE hThread[61];
CWinThread *pT[61];
//创建线程
for(int i=0;i<20;i++){
int a=0;
for(int k=0;k<60;k++)
{
if(iCounter>=950)
break;
pT[k]=NULL;
hThread[k]=NULL;

pT[k]=AfxBeginThread(Athread,(LPVOID)GetSafeHwnd());
if(pT[k]!=NULL)
{
a++;
hThread[k]=pT[k]->m_hThread;
}
}
WaitForMultipleObjects(a,hThread,TRUE,INFINITE);
}

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧