在程序中使用线程读写文件,当线程中读写文件的时间比较长时,程序主界面的操作明显感觉迟缓,这说明线程在读写文件时占用了主程序的大部分CPU时间,但是如果让读写文件的这个工作交给子进程来操作,则子进程读写文件时对主程序的界面进行操作仍然非常顺滑流畅,不会出现使用线程的那种迟缓的情况。这是不是说线程实际上并非真正的多任务?
解决方案 »
- MFC 中单文档修改默认的视图!!!
- 太极语言之父的问题:如何从view中得到所在的程序主框架窗口句柄
- 各位大哥~~~
- 如何将"#ff0000"转换成COLORREF变量
- 请问这句话是什么意思? return const_cast<char *>(pchr);
- VS2010 添加事件处理程序灰色,怎么办只看楼主收藏 回复
- WIN32 编程求助:WIN7 环境下,控件虽然获得焦点,但虚框不显示
- 图像保存问题
- 求一VC画图程序的源代码
- win2k登陆程序一问
- 1>LINK : fatal error LNK1104: cannot open file 'boost_system-vc80-mt-gd-1_36.lib
- CArray的初始化方法,不知道大家有没有总结过?
线程调度是OS的事、、、
就我所知,OS调度对象是线程而不是进程,所以如果你的工作占用CPU的话,那么不管是多线程还是用另一个进程,效果应该是一样的。
有误楼下斧正
跟你说有些事情会阻塞整个系统的,你就是做成子进程都不管用。
个人认为线程的优先级只是这样一个状态:
同进程中的线程优先级只能在代码行之间切换,如果低优先级线程是正在执行诸如调用API函数或者正在读写硬盘等等那些需要等待执行结束才能返回继续执行下一行代码的情形,那么高优先级线程同样必须等待,直到低优先级线程要运行下一行代码时才能继续。
我不知道会不会把控制权交给优先级高的线程, 但起码, 优先级不一样的话, 也就代表优先级低的线程, 进行全系统影响的操作的次数, 也会相应减少. 结果就是你感觉不卡了. 不要把单次的影响系统性能的操作作为大局, 影响你的程序卡还是不卡的, 是这类操作作被连续运行了多少次.
断断续续的运行, 每次运行最多只会使用1ms的时间, 对你的界面肯定不影响啦, 但使用时间是1ms, 然后同等优先级, 即两个线程各只有500ms用, 界面不卡才怪
线程的优先级只能在代码行间切换,即优先级高的线程可能运行几行代码后低优先级线程才能运行一行代码,最低优先级的线程甚至可能必须等待高优先级线程运行结束后才有机会执行,这种线程切换运行很可能只能在代码行之间执行,如果某个线程正在运行的某个API函数未完成或某个磁盘操作未完成,那在此期间其它线程将没机会继续运行,不管它们的优先级为何。
[email protected]
我认为是在机器指令间,这就是为什么线程切换的上下文(context)包含CPU的全部寄存器。
#include<string.h>
#include<CommCtrl.h>
static volatile int stop=0,cc;
DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
void*buffer=GetModuleHandleW(L"kernel32.dll");DWORD c;
HANDLE hFile=CreateFileW(L"D:\\Downloads\\a.dat",GENERIC_WRITE,FILE_SHARE_READ,0,CREATE_ALWAYS,FILE_FLAG_NO_BUFFERING|FILE_FLAG_WRITE_THROUGH,0);
while(stop==0)
{
WriteFile(hFile,buffer,512*16,&c,0);
}
CloseHandle(hFile);
return 0;
}
DWORD WINAPI ThreadProc2(LPVOID lpParameter)
{
while(stop==0)
{
++cc;
}
return 0;
}
LRESULT CALLBACK WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
switch(uMsg)
{
case WM_COMMAND:
switch(LOWORD(wParam))
{
case 0:
stop=0;
CloseHandle(CreateThread(0,0,ThreadProc,0,0,0));
CloseHandle(CreateThread(0,0,ThreadProc2,0,0,0));
break;
case 1:
stop=1;
break;
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_CLOSE:DestroyWindow(hwnd);
case WM_CREATE:return 0;
default: return DefWindowProcW(hwnd,uMsg,wParam,lParam);
}
}BOOL InsertListViewItems(HWND hWndListView, int cItems)
{
LVITEM lvI;wchar_t s[]=L"sdfsodfno"; // Initialize LVITEM members that are common to all items.
lvI.pszText = s;
lvI.mask = LVIF_TEXT | LVIF_IMAGE |LVIF_STATE;
lvI.stateMask = 0;
lvI.iSubItem = 0;
lvI.state = 0; // Initialize LVITEM members that are different for each item.
for (int index = 0; index < cItems; index++)
{
lvI.iItem = index;
lvI.iImage = index;
(*(long*)lvI.pszText)+=1;
(*(long*)(lvI.pszText+2))+=1;
// Insert items into the list.
if (ListView_InsertItem(hWndListView, &lvI) == -1)
return FALSE;
} return TRUE;
}
void Entry(void)
{
static WNDCLASSEXW WindowClass={sizeof(WNDCLASSEXW),0,WindowProc,0,0,(HINSTANCE)0x400000,0,0,0,0,L"wc",0};ATOM ClassAtom;HWND hwnd,lv;MSG msg;LVCOLUMN lvc;
ClassAtom=RegisterClassExW(&WindowClass);
hwnd=CreateWindowExW(0,(LPWSTR)(unsigned long)ClassAtom,0,WS_OVERLAPPEDWINDOW,0,0,600,600,0,0,0,0);
CreateWindowExW(0,L"Button",L"start",WS_VISIBLE|WS_CHILD,10,10,50,50,hwnd,(HMENU)0,0,0);
CreateWindowExW(0,L"Button",L"end",WS_VISIBLE|WS_CHILD,60,10,50,50,hwnd,(HMENU)1,0,0);
lv=CreateWindowExW(0,WC_LISTVIEWW,L"",WS_CHILD | LVS_REPORT | LVS_EDITLABELS|WS_VISIBLE|WS_BORDER,100, 100,400,400,hwnd,(HMENU)3,0,NULL);
lvc.mask = LVCF_WIDTH | LVCF_TEXT;
lvc.pszText = L"ssss";
lvc.cx = 100;
ListView_InsertColumn(lv, 0, &lvc);
InsertListViewItems(lv,400);
UpdateWindow(hwnd);
ShowWindow(hwnd,1);
while(GetMessageW(&msg,0,0,0))DispatchMessageW(&msg);
ExitProcess(0);
}
SetThreadAffinityMask();
SetThreadIdealProcessor(); 上面两个都用过,没效。
PS:我本本是单核的,不知道是否验证了我28L的想法。
复制大文件卡多半是因为缓存把内存撑爆了。
一个线程等待io时将时间分给其他线程,这是多任务操作系统必备的功能
请教如何释放?难道是用Sleep?
线程等待io时就会把时间让出给其他线程,在线程调度上干的事和Sleep没多大区别,我把一次WriteFile的数据量提高到很大也没出现你的卡现象
而且c语言编译成的是机器码,不存在代码行间这个概念,cpu认的是指令,而不是一行行代码
Sleep是没用的,因为你在API中不可能使用它,在单个磁盘读写也不可能用到。你的WriteFile是放在循环中的吗,或者你操作界面时WriteFile还在运行吗,还有你最好在界面上有滚动条控件,然后你拖拉滚动条看看拖拉过程中滚动条是否有停滞现象。
你运行chrome.exe --single-process单进程模式看卡不卡explorer用dllhost不能说明什么问题,资源管理器除了缩略图还干很多事情
你用资源管理器进行全盘搜索,格式化磁盘时都是一个进程,也不卡isee我没用过,但是电驴我这里并不卡,迅雷还是单进程的时候也不怎么卡,3dsmax有时是比较卡,但不是由于io密集
从直觉上来看WriteFile的实现应该是分块的,因为文件可能散布在硬盘上,因此肯定要分块写你可以去看一下fastfat.sys的源代码里面的FatMultipleAsync的实现,它就是在一个循环中,完成对每个run的io
对于fat文件系统WriteFile对有多个run的文件最终会用到这个函数
这个卡不奇怪,因为放大图片是cpu密集型,这个操作会导致界面卡,而保存文件并不是导致卡的关键原因
绝对不是,当界面需要刷新的东西比较多时卡会更为明显。 你说放大图片是cpu密集型,这个卡不奇怪,但是同样的代码我放在子进程的线程中一点不卡,而放在主程序的线程中明显卡的厉害。
都有测试过啊,都一样。你可以以大约如下的代码放在线程中测试下看看:
for(int i = 0; i < iCount; i++)
{
Image srcBmp(imageFileNames[i]);
Bitmap newBmp(srcBmp.GetWidth()*2, srcBmp.GetHeight()*2);
Graphics grnewBmp(&newBmp);
grnewBmp.DrawImage(&srcBmp, 0,0, srcBmp.GetWidth()*2, srcBmp.GetHeight()*2);
newBmp.Save(...);
}