@megoduxa
Человек

В чем при программировании многопоточности возникает ошибка?

Доброго времени суток форумчане! Пишу с таким вопросом: была поставлена задача, написать простенькую программу с многопоточностью. Т.е. у меня есть две задачи и они выполняются друг за другом, сменяя друг друга через определенный интервал времени.
И программа работает какое -то время, а потом просто останавливается и все. Ни ошибок ни вылетов не происходит. При отладке так вообще на одном из шагов пропадает стрелочка, я такое в первый раз увидел.
Буду очень признателен, если вы меня тыкните носом в мои косяки и вообще разъяните что к чему.
Заранее спасибо.

Файл MultiTask.h
#pragma once
void InitManager();
int AddTask(void *Task);
int Task1(char*);
int Task2(char*);
void Manager();

Файл Test.cpp
#include "MultiTask.h"

void main() {
	InitManager();
	AddTask(Task1);
	AddTask(Task2);
	//AddTask(Task2);
	//AddTask(Task1);
	Manager();
}

Файл MultiTask.cpp
#include "MultiTask.h"

#include <conio.h>
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
#define SIZE_OF_BUFFER 1000
#define TIME 200

int N = 0;

typedef struct Task {
	HANDLE hThread;
	int NumberFunction;
	void(*nameOfTask)(int);
	char buffer[SIZE_OF_BUFFER];
}Task;

Task* tasks[10];

void InitManager() {
}

int AddTask(void *task) {
	tasks[N] = (Task*)malloc(sizeof(Task));
	tasks[N]->NumberFunction = N;
	tasks[N]->nameOfTask = *(void(*)(int))task;
	tasks[N]->hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)tasks[N]->nameOfTask,
		tasks[N]->buffer, CREATE_SUSPENDED, NULL);
	for (int i = 0; i < SIZE_OF_BUFFER; i++)
	{
		tasks[N]->buffer[i] = 0;
	}
	N++;
	return 0;
}

int Task1(char* buffer) {
	int i = 0;
	for (i = *(int*)buffer; i < 200; i++) {
		printf("%d ", i);
		*(int*)buffer = i + 1;
		Sleep(50);
	}
	if (i == 200) buffer[4] = 1;
	return 1;
}

int Task2(char* buffer) {
	int i = 100;
	for (i -= *(int*)buffer; i > -1; i--) {
		printf("%d ", i);
		*(int*)buffer = 100 - (i - 1);
		Sleep(50);
	}
	if (i == -1) buffer[4] = 1;
	return 1;
}


void Manager() {
	int FLAG = N;
	int currentTask = 0;

	while (FLAG)
	{
		printf("\n Task: %d \n", tasks[currentTask]->NumberFunction);
		ResumeThread(tasks[currentTask]->hThread);
		Sleep(500);
		SuspendThread(tasks[currentTask]->hThread);

		if (currentTask == N - 1) currentTask = 0;
		else currentTask++;

		int tmp = 0;
		for (int i = 0; i < N; i++) {
			if (tasks[i]->buffer[4] == 0) {
				break;
			}
			if (i == N - 1) FLAG = 0;
		}
	}
	_getch();
}
  • Вопрос задан
  • 131 просмотр
Решения вопроса 1
Rulexec
@Rulexec
Метатеоретик теории типов
В документации SuspendThread написано, что его лучше использовать только отладчикам, а не в реальной жизни.

Calling SuspendThread on a thread that owns a synchronization object, such as a mutex or critical section, can lead to a deadlock if the calling thread tries to obtain a synchronization object owned by a suspended thread.


Кроме того, SuspendThread/ResumeThread инкрементируют/декрементируют счётчик, в зависимости от того поток работает или нет. Проверяйте что возвращают функции, т.к. если, например, ResumeThread провалится, в итоге вы получите рассинхронизацию счётчика и уже никогда не сможете его разбудить.

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

Войдите, чтобы написать ответ

Похожие вопросы