#include <iostream.h>
#include <windows.h>
using namespace std;
const int n = 10;
const int TimeInt = 2;
int pars[n];
HANDLE hTimer;
LARGE_INTEGER li;
struct RR
{
HANDLE hThread;
RR* next;
DWORD dwThread;
};
RR *HEAD = NULL,*TAIL = NULL;
void DelThread();
DWORD WINAPI thread(LPVOID par)
{
int *k = (int*)par;
for(int i = 0;i<5*n;i++)
{
cout<<*k;
Sleep(1);
}
return 0;
}
void NewThread(int i)
{
if (HEAD == NULL)
{
HEAD = new RR;
TAIL = HEAD;
HEAD->next = HEAD;
}
else
{
TAIL->next = new RR;
TAIL = TAIL->next;
TAIL->next = HEAD;
}
TAIL->hThread = CreateThread(NULL,0,thread,&pars,CREATE_SUSPENDED,&(HEAD->dwThread));
return;
}
void DelThread()
{
CloseHandle(HEAD->hThread);
if (HEAD == TAIL)
{
delete HEAD;
TAIL = NULL;
}
else
{
HEAD = HEAD->next;
delete TAIL->next;
TAIL->next = HEAD;
}
}
void main()
{
HANDLE handles[2];
for(int i = 0;i<n;i++)
{
pars = i;
NewThread(i);
}
hTimer = CreateWaitableTimer(NULL, FALSE, NULL);
li.QuadPart = -1;
SetWaitableTimer(hTimer, &li, TimeInt, NULL, NULL, FALSE);
handles[1] = hTimer;
while(HEAD != NULL)
{
handles[0] = HEAD->hThread;
ResumeThread(HEAD->hThread);
DWORD dw = WaitForMultipleObjects(2,handles,FALSE, INFINITE);
switch(dw)
{
case WAIT_OBJECT_0:
cout<<"DELETED";
DelThread();
break;
case WAIT_OBJECT_0+1:
cout<<".";
SuspendThread(HEAD->hThread);
HEAD = HEAD->next;
TAIL = TAIL->next;
break;
default: cout<<"ERROR";
break;
}
}
CloseHandle(hTimer);
system("PAUSE");
return;
}
C++ Карусель (RoundRobin)
Имеется задание: реализовать дисциплину планирования потоков "Карусель" через WinAPI.
Немного поразмыслив и почитав Рихтера, написал вот такой код:
Код:
Эта программа некоторое время работает, а потом "умирает" - останавливается и ничего не выводит=(
Умирает либо на функции SuspendThread(HEAD->hThread);
либо на DWORD dw = WaitForMultipleObjects(2,handles,FA LSE, INFINITE);
Не могу понять, в чем дело=( Может быть, я что-то неправильно делаю? Подскажите бедному неопытному студенту.
HEAD = new RR;
TAIL = HEAD;
Извиняюсь, если не по делу, но по-моему ошибка здесь.
Почему же здесь ошибка? Указатель TAIL указывает на последний элемент списка, а HEAD на первый. А когда мы только создаем список, то первый и есть последний.
2. Необходимо значительно увеличить интервалы в функции Sleep() и, соответственно, "квант" процессорного времени TimeInt. Попробуйте для Sleep взять 100 - 150 мс, а для таймера - 1000 мс. Придется подбирать "на слух", методом проб и ошибок, т.к. Вы не используете объекты синхронизации. В этом, на мой взгляд, кроется причина взаимоблокировок, которые имели место в Вашем варианте. Дело в том, что функция Sleep() совершенно не гарантирует, что поток будет "спать" ровно столько, сколько Вы ему задали. Об этом ясно написано у Рихтера. Реальный планировщик потоков Windows может и не дать квант времени "спящему" потоку по истечении указанного в функции интервала. Следовательно, раз Вы не пользуетесь объектами синхронизации, это может привести к тому, что все потоки в одно и то же время "освободятся" от своих "заданий" и окажутся в положении SUSPENDED.