Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Амир_СистПрог.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
90.28 Кб
Скачать
  1. Критические секции

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

// инициализация критической секции

Void InitializeCriticalSection(lpcritical_section lpCriticalSection); // вход в критическую секцию

VOID EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection);

// попытка войти в критическую секцию

BOOL TryEnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection);

// выход из критической секции

VOID LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection);

// разрушение объекта критическая секция

VOID DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection);

Каждая из этих функций имеет единственный параметр, указатель на объект типа CRIТ 1C AL_S ЕС ТI ON. Все ЭТИ фуНКЦИИ, за исключением TryEnterCriticalSection, не возвращают значения. Функция TryEnterCriticalSection возвращает ненулевое значение, если поток вошел в критическую секцию или уже на­ходится в ней, в противном случае функция возвращает значение false. Отметим также, ЧТО функция TryEnterCriticalSection поддерживается только операционной системой Windows 2000.

Пример работы несинхронизированных потоков

#include <windows.h>

#include <iostream.h>

DWORD WINAPI thread(LPVOID)

{

int i,j;

for (j = 0; j < 10; ++j)

{

// выводим строку чисел j for (i = 0; i < 10; ++i)

{

cout « j « ' ' « flush;

Sleep(17);

}

cout « endl;

return 0;

}

int main()

{

int i, j ;

HANDLE hThread;

DWORD IDThread;

hThread=CreateThread(NULL/ 0; thread, NULL, 0, &IDThread); if (hThread == NULL) return GetLastError();

for (j = 10; j < 20; ++j)

{

for (i = 0; i < 10; ++i)

{

// выводим строку чисел j cout « j « ' ' « flush;

Sleep(17);

}

cout « endl;

}

// ждем, пока поток thread закончит свою работу WaitForSingleObject(hThread, INFINITE);

return 0;

}

  1. Задача. Произвести инверсию (перестановка наоборот) массива

#include <iostream>

#include <time.h>

#include <stdlib.h>

const int N = 10;

int main(int argc, char** argv) {

srand(time(0));

int i, A[N], c;

for ( i = 0; i < N; i ++ ){

A[i] = rand()%100;

printf("%d ", A[i]);

}

printf("\n ");

for ( i = 0; i < N/2; i ++ )

{

c = A[i];

A[i] = A[N-1-i];

A[N-1-i] = c;

}

printf("\n Result:\n");

for ( i = 0; i <N; i ++ )

printf("%d ", A[i]);

return 0;

}

Билет № 9

  1. Простое наследование

Наследованием называют конструирование новых более сложных производных классов (классов-потомков) из уже имеющихся базовых классов (классов-родителей) посредством добавления полей и методов. Это – эффективное средство расширения функциональных возможностей существующих классов без их перепрограммирования и повторной компиляции существующих программ.

По определению компонентами производного класса являются:

  • компоненты базового класса, за исключением конструктора, деструктора и компонентной функции, переопределяющей операцию «присваивания» (=);

  • компоненты, добавляемые в теле производного класса.

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

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

class <Имя производного класса >:

<Вид наследования> <Имя базового класса> {<Тело класса>};

Где вид наследования определяется ключевыми словами: private, protected,

Public.

Видимость полей и функций базового класса из производного определяется секцией, в которой находится объявление компонента и видом наследования. Если вид наследования явно не указан, то по умолчанию принимается private.

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

самым простым является наследование вида public (общедоступное), однако при его применении следует помнить, что скрытые в секции private компоненты базового класса в производном все равно недоступны. Соттветственно для обращения к скрытым полям базового класса должны использоваться методы общедоступной или защищенных секций базового класса, например:

Class A

{

int x;

public:

void set_a(int ax){x=ax;}

print_a(){cout<<x;}

};

class B:public A

{

int y;

public:

void set_b(int ax,int bx)

{

set_a(ax); // доступ к скрытому полю x

b=bx;

}

print_b()

{

print_a(); // доступ к скрытому полю x

cout<<y;

}

};

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]