Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 15.11.2008, 21:53   #1
MaTBeu
Eclipse Foundation
Старожил
 
Аватар для MaTBeu
 
Регистрация: 19.09.2007
Сообщений: 2,619
Вопрос File Map

Всем привет. Заранее извиняюсь, что поднимаю затертую до дыр тему. Но я столкнулся с проблемой, которую я не могу решить.
Значит вкратце о программе. Прога создает файл (точнее открывает уже созданный), мэпает его. Потом создаются два потока - один пишет в файл, через отображение, а второй читает из отображения.
Код:
#include <Windows.h>
#include <iostream>
#include <string.h>

CRITICAL_SECTION cs;
void ReadMap(HANDLE h, LPVOID lpVoid, LPTSTR buffer);
void WriteMap(HANDLE h, LPVOID lpVoid, LPTSTR buffer);

DWORD WINAPI ThreadProcWrite(LPVOID lpParametr)
{
	EnterCriticalSection(&cs);
	HANDLE h=(HANDLE)lpParametr;
	LPTSTR buffer=NULL;
	LPVOID lpVoid=NULL;
	WriteMap(h, lpVoid, buffer);
	LeaveCriticalSection(&cs);
	return (0);
}

DWORD WINAPI ThreadProcRead(LPVOID lpParametr)
{
	EnterCriticalSection(&cs);
	HANDLE h=(HANDLE)lpParametr;
	LPTSTR buffer=NULL;
	LPVOID lpVoid=NULL;
	ReadMap(h, lpVoid, buffer);
	LeaveCriticalSection(&cs);
	return (0);
}

void ReadMap(HANDLE h, LPVOID lpVoid, LPTSTR buffer)
{
	h=OpenFileMapping(FILE_MAP_ALL_ACCESS, TRUE, "Map");
	lpVoid=MapViewOfFile(h, FILE_MAP_ALL_ACCESS, 0, 0, 0);
	if(lpVoid==NULL)
	{
		std::cout<<"Error mapping the file\n";
		printf("Error type %d", GetLastError());
	}
	buffer=(LPTSTR)MapViewOfFile(h, FILE_MAP_ALL_ACCESS, 0, 0, 0);//, lpVoid);
	if(buffer==NULL)
		printf("Error type %d", GetLastError());
	std::cout<<buffer;
}

void WriteMap(HANDLE h, LPVOID lpVoid, LPTSTR buffer)
{
	h=OpenFileMapping(FILE_MAP_ALL_ACCESS, TRUE, "Map");
	lpVoid=MapViewOfFile(h, FILE_MAP_ALL_ACCESS, 0, 0, 0);
	if(lpVoid==NULL)
	{
		std::cout<<"Error mapping the file\n";
		printf("Error type %d", GetLastError());
	}
	strcpy(buffer, "MaTBeu");
	if(!FlushViewOfFile( buffer, lstrlen( buffer ) ))
		printf("Error type %d", GetLastError());
	buffer=(LPTSTR)MapViewOfFile(h, FILE_MAP_ALL_ACCESS, 0, 0, 0);//, lpVoid);
	if(buffer==NULL)
		printf("Error type %d", GetLastError());
	else
		std::cout<<buffer;
}

int main()
{
	HANDLE hFile;
	HANDLE hMap;
	HANDLE hThreads[2];
	DWORD dwId, dwId1;
	LPTSTR buffer;
	LPVOID lpVoid;
	InitializeCriticalSection(&cs);
	hFile=CreateFile("..\\file.txt", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	hMap=CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 100, "Map");

	/*hMap=OpenFileMapping(FILE_MAP_ALL_ACCESS, TRUE, "Map");
	lpVoid=MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
	if(lpVoid==NULL)
	{
		std::cout<<"Error mapping the file\n";
		printf("Error type %d", GetLastError());
	}
	buffer=(LPTSTR)MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);//, lpVoid);
	if(buffer==NULL)
		printf("Error type %d", GetLastError());
	std::cout<<buffer;
	strcpy(buffer, "fukckckkfdsadf sdfdsf adf sdf sdaf sdf h");
	if(!FlushViewOfFile( buffer, lstrlen( buffer ) ))
		printf("Error type %d", GetLastError());
	buffer=(LPTSTR)MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);//, lpVoid);
	if(buffer==NULL)
		printf("Error type %d", GetLastError());
	else
		std::cout<<buffer;*/

		EnterCriticalSection(&cs);
		hThreads[0]=CreateThread(NULL, 0, ThreadProcWrite, (LPVOID)hMap, 0, &dwId);
		//hThreads[1]=CreateThread(NULL, 0, ThreadProcRead, (LPVOID)hMap, 0, &dwId1);
		LeaveCriticalSection(&cs);

		CloseHandle(hFile);
		CloseHandle(hMap);
	return 0;
}
Значит трабла вот в чем. Когда начинает выполняться чтение, то прога доходит до вывода считанного на экран а потом в Output пишет, что подгружены длл, но при этом прога начинает выполняться сначала!!! Такая же ситуация с записью. С записью даже хуже - там даже не доходит до записи в файл через мапу. Стопорит на строке
Код:
strcpy(buffer, "MaTBeu");
дальше рестарт проги. Я просто в ступоре.
ПыСы: главная особенность в чем - если я пишу без потоков, а просто вот в main, прямым кодом (в проге закоментил), то все пашет нормально. А с потоками - никак.
Подскажите пожалуйста, в чем может быть проблема.

Последний раз редактировалось rpy3uH; 16.11.2008 в 15:45.
MaTBeu вне форума Ответить с цитированием
Старый 16.11.2008, 13:42   #2
MaTBeu
Eclipse Foundation
Старожил
 
Аватар для MaTBeu
 
Регистрация: 19.09.2007
Сообщений: 2,619
По умолчанию

Все, прога не рестартиться - проблема была в том, что на строке
Код:
strcpy(buffer, "MaTBeu");
вылетал эксепшен типа невозможно записать по нулевому адресу. Это я исправил (кое-как). Но возникла другая проблема - поток писатель не хочет писать в файл. Все проходит без ошибок
Код:
if(!FlushViewOfFile( buffer, lstrlen( buffer ) ))
		printf("Error type %d", GetLastError());
здесь тож все акей, возвращает TRUE. Но на самом деле ничего не пишется. Вот если в main писать - то нормально. А вот в потоке никак.
Вот код процедуры записи (та которую юзает поток)
Код:
DWORD WINAPI ThreadProcWrite(LPVOID lpParametr)
{
	EnterCriticalSection(&cs);
	HANDLE h=(HANDLE)lpParametr;
	LPSTR buffer="";
	h=OpenFileMapping(FILE_MAP_ALL_ACCESS, TRUE, "Map");
	buffer=(LPSTR)MapViewOfFile(h, FILE_MAP_ALL_ACCESS, 0, 0, 0);
	if(buffer==NULL)
		printf("Error type %d", GetLastError());
	else
		std::cout<<buffer<<std::endl;
	buffer=st;
	if(!(FlushViewOfFile(buffer, lstrlen(buffer))))
		printf("Error type %d", GetLastError());
	else
	{
		buffer=(LPSTR)MapViewOfFile(h, FILE_MAP_ALL_ACCESS, 0, 0, 0);
		if(buffer==NULL)
			printf("Error type %d", GetLastError());
		else
			std::cout<<buffer<<std::endl;
	}
	LeaveCriticalSection(&cs);
	return (0);
}
ПыСы: аналогичная проблема с разными процессами (что, вобщем-то вполне логично). Открывает, читает, говорит, что пишет нормально, опять читает, а там ниче не изменилось...

Последний раз редактировалось MaTBeu; 16.11.2008 в 15:51.
MaTBeu вне форума Ответить с цитированием
Старый 16.11.2008, 15:51   #3
rpy3uH
добрый няша
Старожил
 
Аватар для rpy3uH
 
Регистрация: 29.10.2006
Сообщений: 4,804
По умолчанию

вызывай в конце UnmapViewOfFile. И желательно закрывать все хендлы, в потоках ты этого не делаешь
rpy3uH вне форума Ответить с цитированием
Старый 16.11.2008, 16:01   #4
MaTBeu
Eclipse Foundation
Старожил
 
Аватар для MaTBeu
 
Регистрация: 19.09.2007
Сообщений: 2,619
По умолчанию

Спасибо, исправил. Но все же, не могли бы вы ответить на мой вопрос - как заставить поток другого процесса писать в отображение? (Ну через FlushViewOfFile или как там).
Тоесть есть три процесса. Первый (он же главный), создает отображение. Проверяет его. Потом создает дочерний процесс, который читает из отображения. Это все работает нормально. Потом главный поток создает дочерний процесс-писатель. Который пишет в отображение... Вот тут и не работает.
Главный процесс:
Код:
#include <Windows.h>
#include <iostream>
#include <string>

int main()
{
	HANDLE hFile;
	HANDLE hMap;
	LPVOID lpBaseAddress;
	STARTUPINFO si;
	_PROCESS_INFORMATION piReader, piWriter;

	GetStartupInfo(&si);

	/*Creating a file*/
	hFile=CreateFile("..\\file.txt", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	hMap=CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 20, "Map");
	hMap=OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, "Map");
	lpBaseAddress=MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
	if(lpBaseAddress == NULL)
		printf("Error code %d", GetLastError());
	else
	{
/*Reader*/
		if(CreateProcess("D:\\Documents and Settings\\Admin\\Мои документы\\Visual Studio 2008\\Projects\\PReader\\Debug\\PReader.exe",
			"", NULL, NULL, false,
			NORMAL_PRIORITY_CLASS, NULL,
			NULL, &si, &piReader))
			std::cout<<"Reader created\n";
		else
			std::cout<<"Reader is not created\n";
		WaitForSingleObject(piReader.hProcess, INFINITE);
/*Writer*/
		if(CreateProcess("D:\\Documents and Settings\\Admin\\Мои документы\\Visual Studio 2008\\Projects\\PWriter\\Debug\\PWriter.exe",
			"", NULL, NULL, false,
			NORMAL_PRIORITY_CLASS, NULL,
			NULL, &si, &piWriter))
			std::cout<<"Writer created\n";
		else
			std::cout<<"Writer is not created\n";
		WaitForSingleObject(piWriter.hProcess, INFINITE);
	}
	UnmapViewOfFile(lpBaseAddress);
	CloseHandle(hMap);
	CloseHandle(hFile);
	return 0;
}
Читателя я думаю не нада приводить, так что процесс-писатель:
Код:
#include <Windows.h>
#include <iostream>

int main()
{
	HANDLE hMap;
	LPSTR buffer;
	hMap=OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, "Map");
	if(hMap==NULL)
		printf("Error code %d \n", GetLastError());
	else
	{
		buffer=(LPSTR)MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
		std::cout<<"Previous information: "<<buffer<<std::endl;
		buffer="BuccapuoH";
		if(!(FlushViewOfFile(buffer, lstrlen(buffer))))
			printf("Error type %d", GetLastError());
		else
		{
			buffer=(LPSTR)MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
			if(buffer==NULL)
				printf("Error type %d", GetLastError());
			else
				std::cout<<"Changed data: "<<buffer<<std::endl;
		}
	}
	std::cout<<"Writer executes\n";
	CloseHandle(hMap);
	return 0;
}

Последний раз редактировалось MaTBeu; 16.11.2008 в 16:05.
MaTBeu вне форума Ответить с цитированием
Старый 16.11.2008, 16:27   #5
rpy3uH
добрый няша
Старожил
 
Аватар для rpy3uH
 
Регистрация: 29.10.2006
Сообщений: 4,804
По умолчанию

вызов FlushViewOfFile заканчивается ошибкой?
rpy3uH вне форума Ответить с цитированием
Старый 17.11.2008, 15:38   #6
MaTBeu
Eclipse Foundation
Старожил
 
Аватар для MaTBeu
 
Регистрация: 19.09.2007
Сообщений: 2,619
Радость

Нет все в порядке проходит. Короче FlushViewOfFile не скидывает буфер, а только создает вид, что скидывает. Короче я все поправил, дело было в том, что нужно было строку LPTSTR, тоесть ЮНИКОД писать, а я писал обычными LPSTR. По ходу проблема была в этом.
На всякий случай привожу полный текст программы (может кому пригодится)
Код:
#include <Windows.h>
#include <iostream>
#include <string>
#include "CRWLock.h"		//это мне надо было схему синхронизации еще прибацать сюда
#include <stdlib.h>


CRWLock *locker;

DWORD WINAPI Read(LPVOID lpParam)
{
	/*получение общего доступа для чтения*/
	locker->AcquireLockShared();
	HANDLE hMap;
	LPSTR buffer;
	std::cout<<"Begin reading...\n";
	hMap=OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, "Map");
	if(hMap==NULL)
		printf("(Open mapping)Error code %d \n", GetLastError());
	else
	{
		buffer=(LPSTR)MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
		std::cout<<buffer<<std::endl;
	}
	CloseHandle(hMap);
	std::cout<<"END reading...\n";
	locker->ReleaseLock();
	return 0;
}

DWORD WINAPI Write(LPVOID lpParam)
{
	/*Получение эксклюзивного доступа для записи*/
	locker->AcquireLockExclusive();
	HANDLE hMap;
	LPTSTR buffer;
	LPTSTR cmd=(LPTSTR)lpParam;
	LPVOID lpBase=NULL;
	std::cout<<"Begin writing....\n";
	hMap=OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, "Map");
	if(hMap==NULL)
		printf("(Open mapping)Error code %d \n", GetLastError());
	else
	{
		lpBase=MapViewOfFile(hMap, FILE_MAP_WRITE, 0, 0, 0);
		buffer=(LPTSTR)MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
		std::cout<<"Previous information: "<<buffer<<std::endl;
		strcpy(buffer, cmd);
		if(!FlushViewOfFile(buffer, lstrlen(buffer)))
			printf("(Flush)Error type %d", GetLastError());
		else
		{
			buffer=(LPTSTR)MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
			if(buffer==NULL)
				printf("(Map view)Error type %d", GetLastError());
			else
				std::cout<<"Changed data: "<<buffer<<std::endl;
		}
	}
	Sleep(2000);
	std::cout<<"END WRITING\n";
	CloseHandle(hMap);
	locker->ReleaseLock();
	return 0;
}

int main()
{
	HANDLE hFile;
	HANDLE hMap;
	LPVOID lpBaseAddress;
	locker=new CRWLock();
	HANDLE hReader[3];
	HANDLE hWriter;
	DWORD dwReaderOne, dwReaderTwo, dwReaderThree;
	DWORD dwWriter;
	LPTSTR str[10]={"fdfds", "123243", "3124df", "43254", "312wedw", "r4ewed", "sdfsf", "dasdsf", "dqwdas", "dasgfd"};

/*Создаем файл (открываем имеющийся)*/
	system("cls");
	hFile=CreateFile("..\\file.txt", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
/*Создаем отображение файла в памяти*/
	hMap=CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 100, "Map");
/*Открываем отображение (для проверки)*/
	hMap=OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, "Map");
/*отображаем файл на адресное пространство процесса*/
	lpBaseAddress=MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
/*если отображение = NULL, значит произошла ошибка... ее и выводим*/
	if(lpBaseAddress == NULL)
		printf("Error code %d", GetLastError());
	else
	{
		for(int i=0; i<10; i++)
		{
			hReader[0]=CreateThread(NULL, 0, Read, NULL, 0, &dwReaderOne);
			hReader[1]=CreateThread(NULL, 0, Read, NULL, 0, &dwReaderTwo);
			hReader[2]=CreateThread(NULL, 0, Read, NULL, 0, &dwReaderThree);
			hWriter=CreateThread(NULL, 0, Write, (LPVOID)str[i], 0, &dwWriter);
		}
	}
	/*ждем завершения работы читателей*/
	WaitForMultipleObjects(3, hReader, TRUE, INFINITE);
	/*ждем завершения работы писателя*/
	WaitForSingleObject(hWriter, INFINITE);
	/*удаляем изображение из памяти*/
	UnmapViewOfFile(lpBaseAddress);
	CloseHandle(hMap);
	CloseHandle(hFile);
	/*удаляем защелку*/
	delete locker;
	return 0;
}
Вобщем как говорится, всем спасибо, тему можно закрывать.
MaTBeu вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
File of... GreenDan Общие вопросы Delphi 4 25.08.2008 22:04
file of byte medikk Общие вопросы Delphi 1 11.08.2008 16:00
record/file potion Паскаль, Turbo Pascal, PascalABC.NET 3 10.05.2008 20:15
Google Map API qwestor PHP 3 22.01.2008 08:12
Проблемы с file HSALF Общие вопросы Delphi 3 21.06.2007 19:27