////////////////////////////////////////////////// // //实验四:使用文件映射对象实现线程间同步 // //学号:和谐 // //姓名:和谐 // //时间: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文件所在的目录呢?