zoukankan      html  css  js  c++  java
  • 一个有问题的程序

    
    
    //////////////////////////////////////////////////
    //
    //实验四:使用文件映射对象实现线程间同步
    //
    //学号:和谐
    //
    //姓名:和谐
    //
    //时间:2012年5月21日
    //
    //////////////////////////////////////////////////
    //
    //本程序创建一个27字节的文件,填进去26个字母,结尾是NULL
    //然后创建两个线程
    //一个将大写转化为小写并输出,一个将小写转化为大写并输出
    //
    //////////////////////////////////////////////////
    #include <Windows.h>
    #include <stdio.h>
    #include <ctype.h>
    #define N 26
    
    DWORD WINAPI ThreadProc_1(LPVOID lpParam);
    DWORD WINAPI ThreadProc_2(LPVOID lpParam);
    
    int main(int argc, char** argv)
    {
        //在当前目录下创建一个"data.dat"文件
        WCHAR path[MAX_PATH];
        DWORD dwRet = GetCurrentDirectory(MAX_PATH, path);
        lstrcat(path, L"\\data.dat");
    
        //PWCHAR path = L".\\data.dat";
        HANDLE file_create = CreateFile(
            path,
            FILE_ALL_ACCESS,
            FILE_SHARE_READ|FILE_SHARE_WRITE, 
            NULL,
            CREATE_ALWAYS,
            FILE_FLAG_RANDOM_ACCESS,
            NULL);
        if(file_create == NULL)
        {
            printf("创建文件失败!\n");
            exit(0);
        }
        if(GetLastError() == ERROR_ALREADY_EXISTS)
        {
            printf("将已存在的文件覆盖!\n");
        }
    
        //写入26个小写字母
        char table[N+1];
        for(int i=0; i<N; i++)
        {
            table[i] = 'a'+i;
        }
        table[N] = '\0';
        DWORD bytes_written = 0;
        if(WriteFile(
            file_create,
            table,
            N+1,
            &bytes_written,
            NULL) == 0)
        {
            printf("写入文件失败!\n");
            exit(0);
        }
    
        //创建文件映射
        HANDLE file_map = CreateFileMapping(file_create,
            NULL,
            PAGE_READWRITE,
            0,
            N+1,
            L"miao");
        if(file_map == NULL)
        {
            printf("创建文件映射失败!\n");
            exit(0);
        }
    
        //创建互斥对象
        HANDLE ghMutex = CreateMutex(
            NULL,
            false,
            TEXT("xiaoma"));
        if(ghMutex == NULL)
        {
            printf("创建互斥对象失败!\n");
            exit(0);
        }
    
        //创建子线程
        HANDLE hThread_1,hThread_2;
        hThread_1 = CreateThread(
            NULL,
            0,
            ThreadProc_1,
            file_map,//这里不必进行强制转化
            0,
            NULL);
        hThread_2 = CreateThread(
            NULL,
            0,
            ThreadProc_2,
            file_map,
            0,
            NULL);
    
        Sleep(1000);
        CloseHandle(file_create);
        CloseHandle(file_map);
        //程序结束,删除文件,返回
        int iret = DeleteFile(path);
        if(iret == 0)
        {
            printf("删除文件失败!\n");
            DWORD err = GetLastError();
            switch(err)
            {
            case ERROR_FILE_NOT_FOUND:
                printf("cannot find the file!\n");
                break;
            case ERROR_ACCESS_DENIED:
                printf("this file is read only!\n");
                break;
            default:
                break;
            }
            getchar();
        }
        return 0;
    }
    
    DWORD WINAPI ThreadProc_1(LPVOID lpParam)
    {
        for(int k=0; k<100; k++)
        {
            HANDLE ghMutex = OpenMutex(MUTEX_ALL_ACCESS, false, TEXT("xiaoma"));
            if(ghMutex == NULL)
            {
                printf("error!\ncannot open the mutex!\n");
                return -1;
            }
            if(WaitForSingleObject(ghMutex, INFINITE) == WAIT_OBJECT_0)
            {
                //打开文件映射
                HANDLE  file_map = lpParam;
                LPVOID data = MapViewOfFile(
                    file_map,
                    FILE_MAP_ALL_ACCESS,
                    0,
                    0,
                    N+1);
                if(data == NULL)
                {
                    printf("打开文件映射失败!\n");
                    return -1;
                }
    
                //如果文件中字符为小写,
                //则将小写转化为大写
                char* temp = (char*)data;
                if(islower(temp[0]) != FALSE)
                {
                    printf("原始字符串:\n%s\n",temp);
                    for(int i=0; i<N; i++)
                    {
                        temp[i] = toupper(temp[i]);
                    }
                    printf("转化为大写之后的字符串:\n%s\n\n",temp);
                }
                UnmapViewOfFile(data);
                ReleaseMutex(ghMutex);
            }
        }
        return 0;
    }
    DWORD WINAPI ThreadProc_2(LPVOID lpParam)
    {
        for(int k=0; k<100; k++)
        {
            HANDLE ghMutex = OpenMutex(MUTEX_ALL_ACCESS, false, TEXT("xiaoma"));
            if(ghMutex == NULL)
            {
                printf("error!\ncannot open the mutex!\n");
                return -1;
            }
            if(WaitForSingleObject(ghMutex, INFINITE) == WAIT_OBJECT_0)
            {
                //打开文件映射
                HANDLE  file_map = lpParam;
                LPVOID data = MapViewOfFile(
                    file_map,
                    FILE_MAP_ALL_ACCESS,
                    0,
                    0,
                    N+1);
                if(data == NULL)
                {
                    printf("打开文件映射失败!\n");
                    return -1;
                }
    
                //如果文件中字符为大写,
                //则将大写转化为小写
                char* temp = (char*)data;
                if(isupper(temp[0]) != FALSE)
                {
                    printf("原始字符串:\n%s\n",temp);
                    for(int i=0; i<N; i++)
                    {
                        temp[i] = tolower(temp[i]);
                    }
                    printf("转化为小写之后的字符串:\n%s\n\n",data);
                }
                UnmapViewOfFile(data);
                ReleaseMutex(ghMutex);
            }
        }
        return 0;
    }
    
    
    
     

    关于这个程序的问题有两点

    第一,创建的进程,其返回值返回到哪里了

    第二,创建的文件在哪里?为何运行的时候我在当前目录下没找到?

    第二个问题已解决。我本来想着直接创建文件的时候,在前面加上".\\"就可以在当前文件下创建了

    结果不是的。现在用GetCurrentDirectory函数取得当前目录然后加上文件名实现了

    但是又引出了新的问题:

    为什么这时候创建的文件所在目录不是程序编译链接生成的exe文件所在的目录呢?

  • 相关阅读:
    Activity生命周期回顾
    Android Camera拍照 压缩
    Android获取相册图片
    Android 常用系统控件
    Java synchronized详解
    Android输入法开发
    Android Toast和Notification
    Extjs 自定义控件
    在Extjs中动态增加控件
    数据库中存储js代码无法json解析
  • 原文地址:https://www.cnblogs.com/02xiaoma/p/2512183.html
Copyright © 2011-2022 走看看