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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 12.04.2010, 18:08   #1
Sparky
Участник клуба
 
Аватар для Sparky
 
Регистрация: 15.05.2009
Сообщений: 1,222
По умолчанию использование мьютексов

Добрый вечер есть такая задача:Дан файл, содержащий текст произвольной длины и ключ длиной k символов. Выполнить шифрование этого текста по алгоритму, рассмотренному в задаче № 5 лабораторной работы № 1. Для решения задачи реализовать три потока:
- поток чтения информации из файла в буфер;
- поток шифрования текста;
- поток вывода шифрованного текста в результирующий файл.
Могли бы вы помочь с раставлением захватов и освобождений мьютексов
Единственное, что ограничивает полет мысли программиста-компилятор
Sparky вне форума Ответить с цитированием
Старый 12.04.2010, 18:08   #2
Sparky
Участник клуба
 
Аватар для Sparky
 
Регистрация: 15.05.2009
Сообщений: 1,222
По умолчанию

вот мой код:
Код:
/*
		шифрование текста из файла
*/
#include "stdafx.h"
#include "iostream"
#include "windows.h"
#include "time.h"
//==================================================================================
//					описание  данных и переменных
//==================================================================================

	HANDLE hMutexRead;	 //Мьютекс "информация считана"
    HANDLE hMutexShif;	//Мьютекс "шифрование"
	HANDLE hMutexWrite;	//Мьютекс "информация записана"
	
	FILE *file_in;	//файловая переменная
	FILE *file_out;
	char* file_in_name = "input.txt";	//имя файла
	char* file_out_name = "output.txt";
	char str[255];	//буфер
	std::string key="qwer";	//ключ шифрования
	int count = key.length();	//длина ключа


DWORD WINAPI reader(LPVOID data)	//функция считывания в буфер из файла
{
//захват мьютекса
	int i=0;
	while(!feof(file_in))
	{
		fscanf(file_in,"%c",&str[i]);
		i++;
	}
//освобождение мьютексов
	return 0;
}

DWORD WINAPI shifr(LPVOID data)	//функция шифрования текста
{		

//захват мьютекса
	int i=0;

//=============================================================================
//				вычисление количества повторов
//=============================================================================
	int povtor = strlen(str)/count;	//количество повторений циклов
	int ostatok = strlen(str)%count;	//количество симовлов которые нужно будет еще обработать

//=============================================================================
//				преобразования блоков
//=============================================================================
	int scale = 0;	//коэффициент масштаба
	i=0;
	while (i< povtor) //количество повторов
	{

//=============================================================================
//				переворот символов блока
//=============================================================================
		int j = scale;
		int left = j;
		int rigth = left+count-1;
		for(left,rigth;left<rigth;left++,rigth--)
		{
			char tmp =str[left];
			str[left] = str[rigth];
			str[rigth] = tmp;
		}
//=============================================================================
//				шифрование
//=============================================================================
		int k=j;
		for (int m=0;m<count;m++)
		{
			str[k]= (int)str[k]^(int)key[m];
			k++;
		}
		i++;
		scale=scale+count;
	}

//=============================================================================
//				обработка оставшихся символов
//=============================================================================
	if (ostatok!=0)
	{

//=============================================================================
//				переворот символов
//=============================================================================
		int rigth = strlen(str)-1;
		int left = rigth-ostatok+1;
		int nac = left;
		for(left,rigth;left<rigth;left++,rigth--)
		{
			char tmp =str[left];
			str[left] = str[rigth];
			str[rigth] = tmp;
		}

//=============================================================================
//				шифрование
//=============================================================================
		int m=0;
		for (nac;nac<strlen(str);nac++,m++)
		{
			str[nac]= (int)str[nac]^(int)key[m];
		}
	}
//освобождение мьютексов
	return 0;
}

DWORD WINAPI writer(LPVOID data)	//функция записи в файл
{
//захват мьютекса
	int i=0;
	while(i<strlen(str))
	{
		fprintf(file_out,&str[i]);
		i++;
	}
//освобождение мьютексов
	return 0;
}


void main()
{
	file_in = fopen(file_in_name,"r");	//открытие файла для чтения 
	file_out = fopen(file_out_name,"w");
//==================================================================================
//				создание mutex
//==================================================================================
	hMutexRead = CreateMutex(NULL,true,NULL);
	hMutexShif = CreateMutex(NULL,false,NULL);
	hMutexWrite = CreateMutex(NULL,false,NULL);

//==================================================================================
//			создание потоков
//==================================================================================
	HANDLE hRead = CreateThread(NULL,0,reader,NULL,0,NULL);
	HANDLE hShif = CreateThread(NULL,0,shifr,NULL,0,NULL);
	HANDLE hWrite = CreateThread(NULL,0,writer,NULL,0,NULL);

	HANDLE hThread[3];
	hThread[0] = hRead;
	hThread[0] = hShif;
	hThread[2] = hWrite;

//==================================================================================
//			завершение потоков
//==================================================================================
	WaitForMultipleObjects(3,hThread,true,INFINITE);

	CloseHandle(hRead);
	CloseHandle(hShif);
	CloseHandle(hWrite);

	fclose(file_in);
	fclose(file_out);

	getchar();
}
Единственное, что ограничивает полет мысли программиста-компилятор
Sparky вне форума Ответить с цитированием
Старый 13.04.2010, 14:09   #3
ds.Dante
Старожил
 
Аватар для ds.Dante
 
Регистрация: 06.08.2009
Сообщений: 2,992
По умолчанию

Главная вещь, которую нужно понять - каждый мьютекс соответствует не потокам, а данным, которые не должны изменяться разными потоками одновременно. Поэтому достаточно одного мьютекса на все глобальные переменные.

Нужны ещё две переменные - счётчик прочитанного и счётчик зашифрованного. Если функция шифровки дошла до str[readCount], то она приостанавливается (Sleep(0)). Аналогично, функция записи приостанавливается, если дошла до str[cryptCount]. Мьютекс захватывается непосредственно перед чтением/записью глобальных переменных, и освобождается непосредственно после этого. Поэтому всю работу с глобальными данными желательно сгруппировать в коде максимально компактно. В общем, примерно так:
Код:
void Read()
{
  while (!eof)
  {
    Захват мьютекса;
    Чтение;
    readCount++;
    Освобождение мьютекса;
    Sleep(0); // чтобы позволить другому потоку вклиниться здесь
  }
}

void Crypt()
{
  while (!eof)
  {
    Захват мьютекса;
    if (не дошли до readCount)
    {
        Шифруем;
        cryptCount ++;
    }
    Освобождение мьютекса;
    Sleep(0);
  }
}

void Write()
{
  while (!eof)
  {
    Захват мьютекса;
    if (не дошли до cryptCount)
    {
        Записываем;
    }
    Освобождение мьютекса;
    Sleep(0);
  }
}
ds.Dante вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
использование мьютексов Sparky Win Api 5 07.04.2010 12:27
Использование подпрограмм inferno fm Общие вопросы Delphi 2 19.09.2009 18:37
Использование while и while do prikolist Общие вопросы C/C++ 20 06.04.2009 18:40
Использование обьектов UberStas Помощь студентам 2 13.06.2008 18:55
использование TThread amandra Общие вопросы Delphi 6 03.05.2008 03:13