Выбрасывается исключение в 2х поточной программе
Задача распараллелить вычисление выражения MA = max(Z)*MO+e*(MT*MS) в 2х потоках, где e-константа, Z-вектор, а MA, MO, MT, MS-матрицы. Использовать семафоры, мьютексы, события, критические секции. Все этапы указаны в коде комментариями. Но при запуске выбрасывается исключение:
Вызвано исключение по адресу 0x006A454A в PPKS_Lab1_Win32.exe: 0xC0000005: нарушение прав доступа при записи по адресу 0xCDCDCDCD.
Собственно, код:
#include <iostream>
#include <Windows.h>
using namespace std;
typedef int* vector;
typedef int** matrix;
const int N = 100;
const int P = 2;
const int H = N / P;
int e, m;
vector Z = new int[N];
matrix MO = new vector[N], MT = new vector[N],
MS = new vector[N], MA = new vector[N];
HANDLE E_12, E_21;
HANDLE Mtx;
HANDLE sem1, sem2, semMA;
CRITICAL_SECTION CrSection;
/*=============================T1=============================*/
void T1() {
int e1, m1, s;
matrix MT1 = new vector[N];
for (int i = 0; i < N; i++)
{
MT1[i] = new int[N];
}
cout << "\nThread T1 started" << endl;
//1. Введення MT, Z, e
matrix MA = new vector[N];
for (int i = 0; i < N; i++) {
MA[i] = new int[N];
}
e = 1;
for (int i = 0; i < N; i++)
{
MT[i] = new int[N];
}
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
MT[i][j] = 1;
}
}
vector Z = new int[N];
for (int i = 0; i < N; i++) {
Z[i] = 1;
}
//2.Сигнал задачі Т2 про введення MT, Z, e
SetEvent(E_12);
//3.Чекати на введення MO, MS у задачі Т2
WaitForSingleObject(E_21, INFINITE);
//4.Обчислення m1 := max(ZH)
m1 = 0;
for (int i = 0; i < H; i++)
{
if (Z[i] > m1) {
m1 = Z[i];
}
}
//5.Обчислення m := max (m, m1)
EnterCriticalSection(&CrSection);
m = max(m, m1);
LeaveCriticalSection(&CrSection);
//6.Сигнал T2 про завершення обчислень m
ReleaseSemaphore(sem1, 1, NULL);
//7.Чекати на завершення обчислень m в T2
WaitForSingleObject(sem2, INFINITE);
//8.Копіювати MT1 := MT
EnterCriticalSection(&CrSection);
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
MT1[i][j] = MT[i][j];
}
}
LeaveCriticalSection(&CrSection);
//9.Копіювати e1 := e
EnterCriticalSection(&CrSection);
e1 = e;
LeaveCriticalSection(&CrSection);
//10.Копіювання m1 := m
WaitForSingleObject(Mtx, INFINITE);
m1 = m;
ReleaseMutex(Mtx);
//11.Обчислення MAH = m∙MOH + e∙(MT∙MSH)
for (int i = 0; i < H; i++) {
for (int j = 0; j < N; j++) {
s = 0;
for (int k = 0; k < N; k++) {
s += MS[i][k] * MT1[k][j];
}
MA[i][j] = m1 * MO[i][j] + e1 * s;
}
}
//12.Чекати на завершення обчислень A в T2
WaitForSingleObject(semMA, INFINITE);
//13.Виведення MA
if (N < 10) {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
cout << MA[i][j] << " ";
}
cout << endl;
}
}
cout << "\nThread T1 finished" << endl;
}
/*=============================T2=============================*/
void T2() {
int e2, m2, s;
matrix MT2 = new vector[N];
for (int i = 0; i < N; i++)
{
MT2[i] = new int[N];
}
cout << "\nThread T2 started" << endl;
//1.Введення MO, MS
for (int i = 0; i < N; i++)
{
MO[i] = new int[N];
MS[i] = new int[N];
}
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
MO[i][j] = 1;
MS[i][j] = 1;
}
}
//2.Сигнал задачі Т1 про введення MO, MS
SetEvent(E_21);
//3.Чекати на введення MT, Z, e у задачі Т1
WaitForSingleObject(E_12, INFINITE);
//4.Обчислення m2 := max(ZH)
m2 = 0;
for (int i = H; i < 2 * H; i++)
{
if (Z[i] > m2) {
m2 = Z[i];
}
}
//5.Обчислення m: = max(m, m2)
EnterCriticalSection(&CrSection);
m = max(m, m2);
LeaveCriticalSection(&CrSection);
//6.Сигнал T1 про завершення обчислень m
ReleaseSemaphore(sem2, 1, NULL);
//7.Чекати на завершення обчислень m в T1
WaitForSingleObject(sem1, INFINITE);
//8.Копіювати MT2 := MT
EnterCriticalSection(&CrSection);
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
MT2[i][j] = MT[i][j];
}
}
LeaveCriticalSection(&CrSection);
//9.Копіювати e2:= e
EnterCriticalSection(&CrSection);
e2 = e;
LeaveCriticalSection(&CrSection);
//10.Копіювання m2: = m
WaitForSingleObject(Mtx, INFINITE);
m2 = m;
ReleaseMutex(Mtx);
//11.Обчислення MAH = m∙MOH+e∙(MT∙MSH)
for (int i = 0; i < H; i++) {
for (int j = 0; j < N; j++) {
s = 0;
for (int k = 0; k < N; k++) {
s += MS[i][k] * MT2[k][j];
}
MA[i][j] = m2 * MO[i][j] + e2 * s;
}
}
//12.Сигнал T1 про завершення обчислень A
ReleaseSemaphore(semMA, 1, NULL);
cout << "\nThread T2 finished" << endl;
}
int main(int argc, char* argv[]) {
cout << "Started Lab1" << endl;
E_12 = CreateEvent(NULL, TRUE, FALSE, NULL);
E_21 = CreateEvent(NULL, TRUE, FALSE, NULL);
InitializeCriticalSection(&CrSection);
Mtx = CreateMutex(NULL, FALSE, NULL);
sem1 = CreateSemaphore(NULL, 0, 1, NULL);
sem2 = CreateSemaphore(NULL, 0, 1, NULL);
semMA = CreateSemaphore(NULL, 0, 1, NULL);
DWORD Tid1, Tid2;
HANDLE threads[] = {
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)T1, NULL, NULL, &Tid1),
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)T2, NULL, NULL, &Tid2)
};
WaitForMultipleObjects(2, threads, true, INFINITE);
CloseHandle(threads[0]);
CloseHandle(threads[1]);
cout << "Ended Lab2" << endl;
system("pause");
return 0;
}