Студопедия — Исходный код программы
Студопедия Главная Случайная страница Обратная связь

Разделы: Автомобили Астрономия Биология География Дом и сад Другие языки Другое Информатика История Культура Литература Логика Математика Медицина Металлургия Механика Образование Охрана труда Педагогика Политика Право Психология Религия Риторика Социология Спорт Строительство Технология Туризм Физика Философия Финансы Химия Черчение Экология Экономика Электроника

Исходный код программы






Проект состоит из нескольких модулей, каждый из которых выполняют свою часть работы. Основной модуль – DBEditor.cpp. Он подключает остальные модули, а также осуществляет создание формы, инициализацию дополнительных потоков и их завершение при завершении работы программы.

// DBEditor.cpp: главный файл проекта.

 

#include "stdafx.h"

#include <windows.h>

#include <commdlg.h>

#include "dbthread.cpp"

#include "frmMain.h"

 

//пространства имен для формы и потоков

using namespace DBEditor;

using namespace DBThread;

 

[STAThreadAttribute]

int main(array<System::String ^> ^args)

{

// Включение визуальных эффектов Windows XP до создания каких-либо элементов управления

Application::EnableVisualStyles();

Application::SetCompatibleTextRenderingDefault(false);

 

//инициализируем критическую секцию

InitializeCriticalSection(&cs);

 

//запуск второго потока

Thread^ oThread = gcnew Thread(gcnew ThreadStart(&ThreadExample::ThreadProc));

oThread->Start();

 

//запускаем фоновый поток

Thread^ fThread = gcnew Thread(gcnew ThreadStart(&DeleteThread::ThreadProc));

//фоновый поток

fThread->IsBackground = true;

//низкий приоритет

fThread->Priority = ThreadPriority::Lowest;

fThread->Start();

 

// Создание главного окна и его запуск

Application::Run(gcnew Form1());

 

//завершаем дополнительные потоки

SetEvent(DBThread::hExitThread);

return 0;

}

Модуль stdafx.h позволяет выполнить подключение других модулей и библиотек до загрузки приложения.

//этот файл может быть включен единожды

#pragma once

//библиотека WinAPI для диалогов

#pragma comment (lib, "comdlg32.lib")

//отключаем некоторые уведомления

#pragma warning(disable: 4996)

#pragma warning(disable: 4244)

Две последние строчки необходимы для скрытия некоторых уведомлений компилятора. Эти уведомления несут информативный характер и не критичны для нашего приложения, но мешают отлаживать программу, так как среди уведомлений зачастую теряются сообщения о критических ошибках.

Модуль frmMain.h создается при помощи конструктора форм и использует платформу.NET для работы с оконными объектами. Весь код данного модуля генерируется автоматически программным дизайнером форм, интерес же представляют лишь обработчики событий контролов формы (нажатие на кнопку, изменение данных в текстовом поле).

private:

//функция ждет, пока не завершится вызванная функция в другом потоке

void WaitForThread() {

int result;

bool Running = true;

while (Running) {

result =::WaitForSingleObject(DBThread::hOkThread, 0);

if (result == WAIT_OBJECT_0) Running = false;

}

}

 

//отображает текущую запись на форме

void ShowCurrentRecord() {

if (DBThread::rec.isdel){

lblItem->ForeColor = System::Drawing::Color::Red;

lblCost->ForeColor = System::Drawing::Color::Red;

lblCount->ForeColor = System::Drawing::Color::Red;

lblDate->ForeColor = System::Drawing::Color::Red;

} else {

lblItem->ForeColor = System::Drawing::Color::Black;

lblCost->ForeColor = System::Drawing::Color::Black;

lblCount->ForeColor = System::Drawing::Color::Black;

lblDate->ForeColor = System::Drawing::Color::Black;

}

String ^s1 = gcnew System::String(DBThread::rec.item);

lblItem->Text = s1;

txtItem->Text = s1;

lblCost->Text = Convert::ToString(DBThread::rec.cost);

txtCost->Text = Convert::ToString(DBThread::rec.cost);

lblCount->Text = Convert::ToString(DBThread::rec.count);

txtCount->Text = Convert::ToString(DBThread::rec.count);

String ^s4 = gcnew System::String(DBThread::rec.date);

lblDate->Text = s4;

txtDate->Text = s4;

lblCurrent->Text = Convert::ToString(DBThread::index) + " из " + Convert::ToString(DBThread::count);

txtSetRec->Text = Convert::ToString(DBThread::index);

}

 

private:

//кнопка открытия базы данных

System::Void btnOpenDatabase_Click(System::Object^ sender, System::EventArgs^ e) {

//устанавливаем событие открытия базы данных

SetEvent(DBThread::hOpenDatabase);

//смотрим результат события

WaitForThread();

if (DBThread::GetRes() == OPENDATABASE_OK) {

String ^s=gcnew System::String(DBThread::PathToFile);

txtDatabase->Text = s;

ShowCurrentRecord();

}

}

private:

//кнопка добавления записи в БД

System::Void btnAdd_Click(System::Object^ sender, System::EventArgs^ e) {

//item

char *str = (char*)(void*)Marshal::StringToHGlobalAnsi(txtItem->Text);

strncpy(DBThread::rec.item, str, sizeof(DBThread::rec.item))[sizeof(DBThread::rec.item) - 1] = 0;

//date

str = (char*)(void*)Marshal::StringToHGlobalAnsi(txtDate->Text);

strncpy(DBThread::rec.date, str, sizeof(DBThread::rec.date))[sizeof(DBThread::rec.date) - 1] = 0;

//cost

DBThread::rec.cost = Convert::ToDouble(txtCost->Text);

//count

DBThread::rec.count = Convert::ToInt32(txtCount->Text);

SetEvent(DBThread::hAddRec);

WaitForThread();

if (DBThread::GetRes() == ADDRECORD_OK) {

ShowCurrentRecord();

}

}

 

private:

//кнопка следующей записи

System::Void btnNext_Click(System::Object^ sender, System::EventArgs^ e) {

SetEvent(DBThread::hNextRec);

WaitForThread();

if (DBThread::GetRes() == READRECORD_OK) {

ShowCurrentRecord();

}

}

private:

//кнопка предыдущей записи

System::Void btnBack_Click(System::Object^ sender, System::EventArgs^ e) {

SetEvent(DBThread::hPrevRec);

WaitForThread();

if (DBThread::GetRes() == READRECORD_OK) {

ShowCurrentRecord();

}

}

private:

//ручное переключение записи

System::Void txtSetRec_TextChanged(System::Object^ sender, System::EventArgs^ e) {

DBThread::IndRec = Convert::ToInt32(txtSetRec->Text);

SetEvent(DBThread::hSetRec);

WaitForThread();

if (DBThread::GetRes() == READRECORD_OK) {

ShowCurrentRecord();

}

}

private:

//кнопка изменения текущей записи

System::Void btnChange_Click(System::Object^ sender, System::EventArgs^ e) {

//item

char *str = (char*)(void*)Marshal::StringToHGlobalAnsi(txtItem->Text);

strncpy(DBThread::rec.item, str, sizeof(DBThread::rec.item))[sizeof(DBThread::rec.item) - 1] = 0;

//date

str = (char*)(void*)Marshal::StringToHGlobalAnsi(txtDate->Text);

strncpy(DBThread::rec.date, str, sizeof(DBThread::rec.date))[sizeof(DBThread::rec.date) - 1] = 0;

//cost

DBThread::rec.cost = Convert::ToDouble(txtCost->Text);

//count

DBThread::rec.count = Convert::ToInt32(txtCount->Text);

SetEvent(DBThread::hChangeRec);

WaitForThread();

if (DBThread::GetRes() == CHANGERECORD_OK) {

ShowCurrentRecord();

}

}

 

private:

//кнопка сортировки записей

System::Void btnSort_Click(System::Object^ sender, System::EventArgs^ e) {

SetEvent(DBThread::hSortRec);

WaitForThread();

if (DBThread::GetRes() == SORTRECORD_OK) {

ShowCurrentRecord();

}

}

private:

//кнопка удаления записи

System::Void btnDelete_Click(System::Object^ sender, System::EventArgs^ e) {

SetEvent(DBThread::hDeleteRec);

WaitForThread();

if (DBThread::GetRes() == DELETERECORD_OK) {

ShowCurrentRecord();

}

}

 

Обращение ко второму потоку, который занимается обработкой базы данных, производится по следующему алгоритму в обработчиках всех событий:

1. Устанавливаем начальные данные, с которыми будет работать поток, если необходимо.

2. Устанавливаем необходимое событие в состояние сигнализации.

3. Ждем, пока поток не завершит необходимые операции и не установит ответное событие в состояние сигнализации (ожидание происходит используя функцию WaitForThread(), которая описана выше).

4. Получаем результат работы функции потока, и если он успешен, то выполняем операции с формой (отображение текущей записи, вывод в поля ввода данных и т.д.)

Модуль dbthread.cpp содержит функции и классы, обеспечивающие работу дополнительных потоков. Два класса обеспечивают работу дополнительного потока, обрабатывающего базу данных, и фонового потока с низким приоритетом, занимающегося удалением записей и последующей дефрагментацией файла. Оба потока при работе с файлом БД используют одну критическую секцию, поэтому одновременная работа двух потоков с одним файлом невозможна.

namespace DBThread {

 

using namespace System;

using namespace System::Windows::Forms;

using namespace System::Threading;

 

//структура записи

struct REC{

char item[21]; //наименование

float cost; //цена

int count; //количество

char date[11]; //дата

bool isdel; //метка удаления

} rec, rec2;

int index, count, IndRec; //текущая запись, количество записей

 

CRITICAL_SECTION cs; //критическая секция

//события для управления потоком

HANDLE hOkThread, hExitThread, hAddRec, hChangeRec, hDeleteRec, hNextRec, hPrevRec, hSetRec, hOpenDatabase, hSortRec, hDelRecF;

static char PathToFile[255];

//дескриптор текущего файла

HANDLE hF;

 

//результат работы потока основные константы результатов

int Res = 0;

const int OPENDATABASE_OK = 100;

const int OPENDATABASE_ERROR = 101;

const int OPENDATABASE_CANCEL = 102;

const int READRECORD_OK = 200;

const int READRECORD_OVER = 201;

const int READRECORD_ERROR = 202;

const int ADDRECORD_OK = 300;

const int ADDRECORD_ERROR = 301;

const int CHANGERECORD_OK = 400;

const int CHANGERECORD_ERROR = 401;

const int SORTRECORD_OK = 500;

const int SORTRECORD_ERROR = 501;

const int DELETERECORD_OK = 600;

const int DELETERECORD_ERROR = 601;

 

//функция возвращает результат работы последней функции потока

int GetRes() {

int s;

s = Res;

Res = 0;

return s;

}

 

//заменяет указанную запись i в файле данными из структуры rec

void ChangeRecordF(int i){

DWORD BytesRead;

//устанавливаем курсор в конец

SetFilePointer(hF, (i - 1) * sizeof(rec), NULL, FILE_BEGIN);

if (!WriteFile(hF, &rec, sizeof(rec), &BytesRead, NULL)||(BytesRead!=sizeof(rec))) {

Res = CHANGERECORD_ERROR;

} else {

if (BytesRead > 0) Res = CHANGERECORD_OK;

}

}

 

//читает указанную запись i в структуру rec

void ReadRecordF1(int i) {

DWORD BytesRead;

//если индекс нужной записи выходит за пределы - завершаем функцию

if ((i < 1)|(i > count)) {

return;

}

//устанавливаем курсор чтения в нужную позицию

SetFilePointer(hF, (i - 1) * sizeof(rec), NULL, FILE_BEGIN);

if (!ReadFile(hF, &rec, sizeof(rec), &BytesRead, NULL)) {

Res = READRECORD_ERROR;

} else {

if (BytesRead>0) {

Res = READRECORD_OK;

}

}

}

 

//читает указанную запись i в структуру rec2

void ReadRecordF2(int i) {

DWORD BytesRead;

//если индекс нужной записи выходит за пределы - завершаем функцию

if ((i < 1)|(i > count)) {

return;

}

//устанавливаем курсор чтения в нужную позицию

SetFilePointer(hF, (i - 1) * sizeof(rec2), NULL, FILE_BEGIN);

if (!ReadFile(hF, &rec2, sizeof(rec2), &BytesRead, NULL)) {

Res = READRECORD_ERROR;

} else {

if (BytesRead>0) {

Res = READRECORD_OK;

}

}

}

 

//класс реализации потока

public ref class ThreadExample {

public:

//основной процесс потока

static void ThreadProc() {

//создаем основные события

//событие завершения работы функции в потоке

hOkThread = CreateEvent(NULL, FALSE, FALSE, NULL);

//событие выхода. Делаем с ручным сбосом, чтобы по этому событию завершались все потоки

hExitThread = CreateEvent(NULL, TRUE, FALSE, NULL);

//событие добавления записи

hAddRec = CreateEvent(NULL, FALSE, FALSE, NULL);

//событие изменения записи

hChangeRec = CreateEvent(NULL, FALSE, FALSE, NULL);

//событие удаления записи

hDeleteRec = CreateEvent(NULL, FALSE, FALSE, NULL);

//событие следующей записи

hNextRec = CreateEvent(NULL, FALSE, FALSE, NULL);

//событие предыдущей записи

hPrevRec = CreateEvent(NULL, FALSE, FALSE, NULL);

//событие конкретной записи

hSetRec = CreateEvent(NULL, FALSE, FALSE, NULL);

//событие конкретной записи

hSortRec = CreateEvent(NULL, FALSE, FALSE, NULL);

//событие открытия базы данных

hOpenDatabase = CreateEvent(NULL, FALSE, FALSE, NULL);

int result;

bool Running = true;

//смотрим, какие из событий "включаются" и выполняем соответствующие действия

while (Running) {

result =::WaitForSingleObject(hExitThread, 0);

if (result == WAIT_OBJECT_0) Running = false;

result =::WaitForSingleObject(hOpenDatabase, 0);

if (result == WAIT_OBJECT_0) OpenDatabase();

result =::WaitForSingleObject(hNextRec, 0);

if (result == WAIT_OBJECT_0) ReadRecord(index + 1);

result =::WaitForSingleObject(hPrevRec, 0);

if (result == WAIT_OBJECT_0) ReadRecord(index - 1);

result =::WaitForSingleObject(hSetRec, 0);

if (result == WAIT_OBJECT_0) ReadRecord(IndRec);

result =::WaitForSingleObject(hAddRec, 0);

if (result == WAIT_OBJECT_0) AddRecord();

result =::WaitForSingleObject(hChangeRec, 0);

if (result == WAIT_OBJECT_0) ChangeRecord(index);

result =::WaitForSingleObject(hSortRec, 0);

if (result == WAIT_OBJECT_0) SortRecord();

result =::WaitForSingleObject(hDeleteRec, 0);

if (result == WAIT_OBJECT_0) DeleteRecord();

}

}

 

//открытие базы данных

static void OpenDatabase() {

OPENFILENAME openFileName;

DWORD sizefile;

DWORD BytesRead;

 

Res = OPENDATABASE_ERROR;

//диалог открытия файла

openFileName.lStructSize = sizeof(openFileName);

openFileName.hwndOwner = NULL;

openFileName.Flags = OFN_HIDEREADONLY;

openFileName.hInstance = NULL;

openFileName.lpstrFilter = "Текстовая база данных(*.txt)\0*.txt\0\0";

openFileName.lpstrCustomFilter = NULL;

openFileName.nMaxCustFilter = 0;

openFileName.nFilterIndex = 1;

openFileName.lpstrFile = PathToFile;

openFileName.nMaxFile = 255;

openFileName.lpstrFileTitle = NULL;

openFileName.lpstrInitialDir = NULL;

openFileName.lpstrTitle = "Открыть...";

openFileName.lpstrDefExt = "txt";

 

//открылся ли файл

if (GetOpenFileName(&openFileName)) {

EnterCriticalSection(&cs);

//закрываем предыдущий открытй файл

CloseHandle(hF);

//и пытаемся открыть новый

hF = CreateFile(PathToFile, GENERIC_READ | GENERIC_WRITE, 0,NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);

if (hF==INVALID_HANDLE_VALUE) {

MessageBox::Show("Ошибка открытия файла");

LeaveCriticalSection(&cs);

SetEvent(hOkThread);

return;

}

if (!ReadFile(hF, &rec, sizeof(rec), &BytesRead, NULL)) {

MessageBox::Show("Ошибка чтения файла");

} else {

//считываем количество записей

index = 0;

if (BytesRead>0) index++;

sizefile = GetFileSize(hF,NULL);

count = sizefile / sizeof(rec);

SetFilePointer(hF, 0, NULL, FILE_BEGIN);

Res = OPENDATABASE_OK;

}

} else {

Res = OPENDATABASE_CANCEL;

}

LeaveCriticalSection(&cs);

SetEvent(hOkThread);

}

 

//считывает запись в структуру rec

static void ReadRecord(int i) {

DWORD BytesRead;

//если индекс нужной записи выходит за пределы - завершаем функцию

if ((i < 1)|(i > count)) {

Res = READRECORD_OVER;

SetEvent(hOkThread);

return;

}

EnterCriticalSection(&cs);

//устанавливаем курсор чтения в нужную позицию

SetFilePointer(hF, (i - 1) * sizeof(rec), NULL, FILE_BEGIN);

if (!ReadFile(hF, &rec, sizeof(rec), &BytesRead, NULL)) {

MessageBox::Show("Ошибка чтения файла");

Res = READRECORD_ERROR;

} else {

if (BytesRead>0) {

index = i;

Res = READRECORD_OK;

}

}

LeaveCriticalSection(&cs);

//функция завершает работу

SetEvent(hOkThread);

}

 

//добавляет данные стуктуры rec в файл

static void AddRecord(){

DWORD BytesRead;

EnterCriticalSection(&cs);

//устанавливаем курсор записи в конец

SetFilePointer(hF, 0, NULL, FILE_END);

if (!WriteFile(hF, &rec, sizeof(rec), &BytesRead, NULL)||(BytesRead!=sizeof(rec))) {

MessageBox::Show("Ошибка записи файла");

Res = ADDRECORD_ERROR;

} else {

if (BytesRead > 0) {

count++;

index = count;

Res = ADDRECORD_OK;

MessageBox::Show("Запись добавлена!");

}

}

LeaveCriticalSection(&cs);

SetEvent(hOkThread);

}

 

//заменяет данные указанной записи i на данные структуры rec

static void ChangeRecord(int i){

DWORD BytesRead;

EnterCriticalSection(&cs);

//устанавливаем курсор записи в нужную позицию

SetFilePointer(hF, (i - 1) * sizeof(rec), NULL, FILE_BEGIN);

if (!WriteFile(hF, &rec, sizeof(rec), &BytesRead, NULL)||(BytesRead!=sizeof(rec))) {

MessageBox::Show("Ошибка записи файла");

Res = CHANGERECORD_ERROR;

} else {

if (BytesRead > 0) {

Res = CHANGERECORD_OK;

MessageBox::Show("Запись изменена!");

}

}

LeaveCriticalSection(&cs);

SetEvent(hOkThread);

}

 

//проверяет, является ли вторая дата больше первой

static bool IsDateSt(char d1[11], char d2[11]) {

char day1[2], day2[2], month1[2], month2[2], year1[4], year2[4];

int df1, df2, mf1, mf2, yf1, yf2;

strncpy(day1, d1, 2);

strncpy(day2, d2, 2);

strncpy(month1, d1 + 3, 2);

strncpy(month2, d2 + 3, 2);

strncpy(year1, d1 + 7, 4);

strncpy(year2, d2 + 7, 4);

df1 = atoi(day1);

df2 = atoi(day2);

mf1 = atoi(month1);

mf2 = atoi(month2);

yf1 = atoi(year1);

yf2 = atoi(year2);

if (yf2 < yf1) { return true; } else {

if ((yf2 == yf1) & (mf2 < mf1)) { return true; } else {

if ((yf2 == yf1) & (mf2 == mf1) & (df2 < df1)) { return true; } else {

return false;

}

}

}

}

 

//сортирует записи пузырьковым методом

static void SortRecord() {

//сортировать нечего

if (count == 0) {

Res = SORTRECORD_ERROR;

SetEvent(hOkThread);

return;

}

EnterCriticalSection(&cs);

//алгоритм работы пузырьковой сортировки

for (int i = count; i > 1; i--)

for (int j = 1; j < i; j++) {

//считываем текущую и следующую запись

ReadRecordF1(j);

ReadRecordF2(j + 1);

if (Res == READRECORD_ERROR) {

Res = SORTRECORD_ERROR;

MessageBox::Show("Ошибка сортировки при чтении параметра!");

LeaveCriticalSection(&cs);

SetEvent(hOkThread);

return;

}

//если дата следующей больше даты предыдущей

if (IsDateSt(rec.date, rec2.date)) {

//то меняем местами записи

ChangeRecordF(j+1);

rec = rec2;

ChangeRecordF(j);

if (Res == CHANGERECORD_ERROR) {

Res = SORTRECORD_ERROR;

MessageBox::Show("Ошибка сортировки при записи параметра!");

LeaveCriticalSection(&cs);

SetEvent(hOkThread);

return;

}

}

}

//устанавливаем на первую запись

index = 1;

ReadRecordF1(index);

Res = SORTRECORD_OK;

MessageBox::Show("Все записи отсортированы по дате!");

LeaveCriticalSection(&cs);

SetEvent(hOkThread);

}

 

//помечает текущую запись как удаленную и вызывает событие удаления

static void DeleteRecord(){

EnterCriticalSection(&cs);

rec.isdel = true;

ChangeRecordF(index);

if (Res == CHANGERECORD_ERROR) {

Res = DELETERECORD_ERROR;

MessageBox::Show("Ошибка записи параметра!");

} else {

Res = DELETERECORD_OK;

}

LeaveCriticalSection(&cs);

SetEvent(hOkThread);

SetEvent(hDelRecF);

}

};

 

//класс потока удаления записей

public ref class DeleteThread {

public:

static void ThreadProc() {

//событие удаления записи

hDelRecF = CreateEvent(NULL, FALSE, FALSE, NULL);

int result;

bool Running = true;

//проверяем события

while (Running) {

result =::WaitForSingleObject(hExitThread, 0);

if (result == WAIT_OBJECT_0) Running = false;

result =::WaitForSingleObject(hDelRecF, 0);

if (result == WAIT_OBJECT_0) DeleteRecord();

}

}

 

//удаляет помеченные для удаления записи из файла

static void DeleteRecord(){

int j = 1;

int i = 1;

EnterCriticalSection(&cs);

//листаем все записи, пока не подойдем к концу

while (i <= count) {

//читаем запись

ReadRecordF1(i);

//записываем текущую запись в новую позицию

ChangeRecordF(j);

//если запись помечена для удаления

if (rec.isdel) j--;//сдвигаем новую позицию назад

i++;

j++;//следующуя запись

}

count = count - (i - j);

//сдвигаем конец файла назад

SetFilePointer(hF, count * sizeof(rec), NULL, FILE_BEGIN);

SetEndOfFile(hF);

LeaveCriticalSection(&cs);

}

};

 

}

 

Функции ChangeRecordF(), ReadRecordF1() и ReadRecordF2 специально вынесены из класса первого потока, так как они используются в обоих потоках. Также в дополнительном потоке существуют похожие функции ChangeRecord() и ReadRecord(). Их отличие в том, что вынесенные функции считывают и изменяют данные «молча», то есть не уведомляют о результатах работы и не сигнализируют о завершении функции основному потоку.

Метод ReadRecord() работает следующим образом: устанавливается курсор чтения в указанную позицию файла, причем позиция равна i*size(rec), т.е. номер записи, которую надо прочитать на размер этой записи (так как все записи имеют одинаковый статичный размер, равный размеру структуры REC. После этого считываем кусок данных из файла, равный размеру записи.

Метод ChangeRecord() работает подобным образом, только вместо чтения данных с указанного места в структуру rec, происходит запись данных в указанное место из структуры rec.

Метод AddRecord() аналогичен методу ChangeRecord(), но запись помещается в конец файла.

Метод SortRecord() позволяет отсортировать записи по полю «Дата», используя пузырьковую сортировку. Принцип метода прост: сравниваем элементы попарно, и исходя из направления сортировки либо меняем ли бо не меняем их местами. В нашем конкретном случае используется два вложенных цикла, первый производит полную сортировку по итерациям, а второй соответственно сравнивает все элементы попарно. Внутри второго цикла считываем текущий и следующий элемент. Если дата следующего меньше даты текущего, то записываем их меняя местами.

Метод DeleteRecord() лишь помечает текущую запись удаленной и сигнализирует событие удаления, чтобы активировать фоновый поток.

Сама операция удаления записи совмещена с дефрагментацией файла (т.е. удалением пустых областей файла путем сдвига всех последующих записей). Для этого производим обход всех записей файла. Считываем запись по индексу чтению, а затем записываем ее же по индексу записи. Изначально оба индекса равны, поэтому все записи остаются на своем месте. Если текущая запись помечена как удаленная, то уменьшаем индекс записи на единицу. При этом следующая запись будет записываться уже на место удаляемой, последующая на место следующей и т.д. Такой способ позволяет правильно удалить сразу несколько помеченных для удаления записей за один обход.


 

Вывод

Процесс (задача) - программа, находящаяся в режиме выполнения. В многозадачной системе реальный процессор переключается с процесса на процесс, но для упрощения модели рассматривается набор процессов, идущих параллельно (псевдопараллельно). Каждому процессу соответствует адресное пространство и одиночный поток исполняемых команд. В многопользовательских системах, при каждом обращении к одному и тому же сервису, приходится создавать новый процесс для обслуживания клиента. Это менее выгодно, чем создать квазипараллельный поток внутри этого процесса с одним адресным пространством. Преимущества использования потоков:

· Упрощение программы в некоторых случаях, за счет использования общего адресного пространства.

· Быстрота создания потока, по сравнению с процессом, примерно в 100 раз.

· Повышение производительности самой программы, т.к. есть возможность одновременно выполнять вычисления на процессоре и операцию ввода/вывода. Пример: текстовый редактор с тремя потоками может одновременно взаимодействовать с пользователем, форматировать текст и записывать на диск резервную копию.

Во время разработки программного продукта я изучил и применил на практике использование нескольких потоков в одном приложении. Это позволило увеличить быстродействие приложения, а также разграничить пользовательский интерфейс и обработку данных в БД.

Также я познакомился и научился применять функции WinAPI для работы с файлами. Это также позволило увеличить быстродействие и упростить программный продукт, так как доступ к файлам осуществлялся напрямую через Windows.

В итоге был разработан конечный программный продукт, позволяющий управлять базой данных. Думаю, полученные знания можно будет применять в дальнейшем для разработки более сложных проектов.


 

Используемая литература

1. А.В. Гордеев. Операционные системы: Учебник для вузов. 2-е изд. – СПб.: Питер, 2007. – 416 с.: ил.

2. С.В. Назаров. Операционные среды, системы и оболочки. Основы структурной и функциональной организации: Учеб.пособие. – М.: КУДИЦ-ПРЕСС, 2007. – 504 с., илл.

3. С.В. Назаров, Л.П. Гудыно, А.А. Кириченко. Операционные системы. Практикум. Под ред. С.В. Назарова – М.: КУДИЦ-ПРЕСС, 2008. – 464 с., илл.

4. В.Г. Олифер, Н.А. Олифер. Сетевые операционные системы: Учебник для вузов. 2-е изд. – СПб.: Питер, 2008. – 669 с.: ил.

5. Д.В. Иртегов. Введение в операционные системы. – 2-е изд., перераб. и доп. – СПб.: БХВ-Петербург, 2008. – 1040 с.: ил. – (Учебное пособие)

6. Х.М. Дейтел, П.Дж. Дейтел, Д.Р. Чофнес. Операционные системы. Основы и принципы: Третье издание. Пер. с англ. – М.: ООО «Бином-Пресс», 2006 г. – 1024 с.: ил.

7. Х.М. Дейтел, П.Дж. Дейтел, Д.Р. Чофнес. Операционные системы. Распределенные системы, сети, безопасность: Третье издание. Пер. с англ. – М.: ООО «Бином-Пресс», 2006 г. – 704 с.: ил.

8. Э. Таненбаум. Современные операционные системы. 2-е изд. – СПб.: Питер, 2006. – 1038 с.: ил.

9. Д. Бэкон, Т. Харрис. Операционные системы. – СПб.: Питер; Киев: Издательская группа BHV, 2004. – 800 с.: ил.

10. Джеффри Рихтер. Windows для профессионалов (программирование в Win32 API для WindowsNT 3.5 и Windows 95) /Пер. с англ. – М.: Издательский отдел «Русская редакция» ТОО «ChannelTradingLtd.», 1995. – 720 с.: ил.

11. Джеффри Рихтер. Windows для профессионалов: создание эффективных Win32 приложений с учетом специфики 64-разрядной Windows /Пер. с англ. – 4-е изд. - Спб.: Питер; М.: Издательство «Русская редакция», 2008. – 722 с.: ил.

12. Ч.Петзолд. Программирование для Windows 95. Том 1: пер. с англ. – СПб.: BHV – Санкт-Петербург, 1997. – 752 с., ил.

13. Ч.Петзолд. Программирование для Windows 95. Том 2: пер. с англ. – СПб.: BHV – Санкт-Петербург, 1997. – 368 с., ил.

 







Дата добавления: 2015-06-15; просмотров: 411. Нарушение авторских прав; Мы поможем в написании вашей работы!



Важнейшие способы обработки и анализа рядов динамики Не во всех случаях эмпирические данные рядов динамики позволяют определить тенденцию изменения явления во времени...

ТЕОРЕТИЧЕСКАЯ МЕХАНИКА Статика является частью теоретической механики, изучающей условия, при ко­торых тело находится под действием заданной системы сил...

Теория усилителей. Схема Основная масса современных аналоговых и аналого-цифровых электронных устройств выполняется на специализированных микросхемах...

Логические цифровые микросхемы Более сложные элементы цифровой схемотехники (триггеры, мультиплексоры, декодеры и т.д.) не имеют...

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

РЕВМАТИЧЕСКИЕ БОЛЕЗНИ Ревматические болезни(или диффузные болезни соединительно ткани(ДБСТ))— это группа заболеваний, характеризующихся первичным системным поражением соединительной ткани в связи с нарушением иммунного гомеостаза...

Решение Постоянные издержки (FC) не зависят от изменения объёма производства, существуют постоянно...

Огоньки» в основной период В основной период смены могут проводиться три вида «огоньков»: «огонек-анализ», тематический «огонек» и «конфликтный» огонек...

Упражнение Джеффа. Это список вопросов или утверждений, отвечая на которые участник может раскрыть свой внутренний мир перед другими участниками и узнать о других участниках больше...

Влияние первой русской революции 1905-1907 гг. на Казахстан. Революция в России (1905-1907 гг.), дала первый толчок политическому пробуждению трудящихся Казахстана, развитию национально-освободительного рабочего движения против гнета. В Казахстане, находившемся далеко от политических центров Российской империи...

Studopedia.info - Студопедия - 2014-2024 год . (0.01 сек.) русская версия | украинская версия