// mult.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include <string>
using namespace std;char buf[50000];
const int PRE_READ_SIZE = 512;
CRITICAL_SECTION CriticalSection;void loadMemory(LPVOID pvoid)
{
char* fileName = (char*)pvoid;
FILE* file = fopen(fileName, "rb");
if(NULL == file)
{
cout << "open file " << fileName << "error.\n";
return;
}
int iOffset = 0;
int iRead = 512;
while(iRead == PRE_READ_SIZE)
{
iRead = (int)fread(buf + iOffset, sizeof(char), PRE_READ_SIZE, file);
iOffset += iRead; //锁定
EnterCriticalSection(&CriticalSection);
cout << "ReadSize:" << iRead << endl;
cout << "TotalSize:" << iOffset << endl;
LeaveCriticalSection(&CriticalSection); }
fread(buf + iOffset, sizeof(char), PRE_READ_SIZE, file);
cout << "ReadSize:" << iRead << endl;
cout << "#####LOAD END#####" << endl;
}int _tmain(int argc, _TCHAR* argv[])
{
DWORD dwThreadId;
char* fileName = "c:\\ACEd.dll";
InitializeCriticalSection(&CriticalSection);
HANDLE h = CreateThread( 
NULL,              // default security attributes
0,                 // use default stack size  
(LPTHREAD_START_ROUTINE)loadMemory,        // thread function 
fileName,             // argument to thread function 
0,                 // use default creation flags 
&dwThreadId);   // returns the thread identifier 
 
//WaitForSingleObject(h,50); for(int i = 0; i < 50; i++)
{
printf("---------------------\n");
Sleep(5);
}
DeleteCriticalSection(&CriticalSection);
return 0;
}
上面的代码我在
//锁定
EnterCriticalSection(&CriticalSection);
cout << "ReadSize:" << iRead << endl;
cout << "TotalSize:" << iOffset << endl;
LeaveCriticalSection(&CriticalSection);
已经锁定了等于一个原子操作,那为什么执行到一半还会切换到主线程去执行printf呢?是我把原理搞错了,还是用错了,本人刚学多线程方面的程序,希望大家帮忙看下,谢谢!

解决方案 »

  1.   

        EnterCriticalSection(&CriticalSection);
            cout << "ReadSize:" << iRead << endl;
            cout << "TotalSize:" << iOffset << endl;
            LeaveCriticalSection(&CriticalSection);
    只是在线中锁了,并且你每个循环又解了,
    改成
    // mult.cpp : 定义控制台应用程序的入口点。
    //#include "stdafx.h"
    #include <windows.h>
    #include <iostream>
    #include <string>
    using namespace std;char buf[50000];
    const int PRE_READ_SIZE = 512;
    CRITICAL_SECTION CriticalSection;void loadMemory(LPVOID pvoid)
    {
        char* fileName = (char*)pvoid;
          //锁定
            EnterCriticalSection(&CriticalSection);
     
        FILE* file = fopen(fileName, "rb");
        if(NULL == file)
        {
            cout << "open file " << fileName << "error.\n";
    LeaveCriticalSection(&CriticalSection);        return;
        }
        int iOffset = 0;
        int iRead = 512;
        while(iRead == PRE_READ_SIZE)
        {
            iRead = (int)fread(buf + iOffset, sizeof(char), PRE_READ_SIZE, file);
            iOffset += iRead;         cout << "ReadSize:" << iRead << endl;
            cout << "TotalSize:" << iOffset << endl;
      
        }
        fread(buf + iOffset, sizeof(char), PRE_READ_SIZE, file);
        cout << "ReadSize:" << iRead << endl;
        cout << "#####LOAD END#####" << endl;
    LeaveCriticalSection(&CriticalSection);}int _tmain(int argc, _TCHAR* argv[])
    {
        DWORD dwThreadId;
        char* fileName = "c:\\ACEd.dll";
        InitializeCriticalSection(&CriticalSection);
        HANDLE h = CreateThread( 
            NULL,              // default security attributes
            0,                 // use default stack size  
            (LPTHREAD_START_ROUTINE)loadMemory,        // thread function 
            fileName,             // argument to thread function 
            0,                 // use default creation flags 
            &dwThreadId);   // returns the thread identifier 
     
        //WaitForSingleObject(h,50);
    EnterCriticalSection(&CriticalSection);
        for(int i = 0; i < 50; i++)
        {
            printf("---------------------\n");
            Sleep(5);
        }
    LeaveCriticalSection(&CriticalSection);
        DeleteCriticalSection(&CriticalSection);
        return 0;
    }其实你应该用信号更合式
      

  2.   

    EnterCriticalSection(&CriticalSection)是原子操作,指的的这个函数调用的过程中cpu不会被切换,至于这个函数执行以后,照样会切换到别的线程,所以才要用临界区嘛,用同一个临界区保护共享数据。
    如果因为进入一个临界区,就不让别的进程执行,那我直接在进入临界区后放一个死循环,你的机器还能执行别的程序么~
      

  3.   


    // mult.cpp : 定义控制台应用程序的入口点。
    //#include "stdafx.h"
    #include <windows.h>
    #include <iostream>
    #include <string>
    using namespace std;char buf[50000];
    const int PRE_READ_SIZE = 512;
    CRITICAL_SECTION CriticalSection;void loadMemory(LPVOID pvoid)
    {
        char* fileName = (char*)pvoid;
          //锁定
            EnterCriticalSection(&CriticalSection);
     
        FILE* file = fopen(fileName, "rb");
        if(NULL == file)
        {
            cout << "open file " << fileName << "error.\n";
    LeaveCriticalSection(&CriticalSection);        return;
        }
        int iOffset = 0;
        int iRead = 512;
        while(iRead == PRE_READ_SIZE)
        {
            iRead = (int)fread(buf + iOffset, sizeof(char), PRE_READ_SIZE, file);
            iOffset += iRead;         cout << "ReadSize:" << iRead << endl;
            cout << "TotalSize:" << iOffset << endl;
      
        }
        fread(buf + iOffset, sizeof(char), PRE_READ_SIZE, file);
        cout << "ReadSize:" << iRead << endl;
        cout << "#####LOAD END#####" << endl;
    LeaveCriticalSection(&CriticalSection);}int _tmain(int argc, _TCHAR* argv[])
    {
        DWORD dwThreadId;
        char* fileName = "c:\\ACEd.dll";
        InitializeCriticalSection(&CriticalSection);
        HANDLE h = CreateThread( 
            NULL,              // default security attributes
            0,                 // use default stack size  
            (LPTHREAD_START_ROUTINE)loadMemory,        // thread function 
            fileName,             // argument to thread function 
            0,                 // use default creation flags 
            &dwThreadId);   // returns the thread identifier 
     
        //WaitForSingleObject(h,50);
        for(int i = 0; i < 50; i++)
        {
     EnterCriticalSection(&CriticalSection);
            printf("---------------------\n");
     LeaveCriticalSection(&CriticalSection);  // 不能保证每隔两行输出
        }
        return 0;
    }