| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
Мое почтение, дамы и господа! 8)))
И вот опять намечается серия статей, про которую ничего заведомо не известно. Я ничего не могу сказать про количество статей, регулярность их выхода. Я даже не могу гарантировать, что задуманное будет доведено до логического финала, ибо эта тема для одного человека непреподъемна.
На форуме команды Acolytez (http://forum.acolytez.com) в разделе про программирование мы уже начали обсуждать данный вопрос. Для тех, кто не в курсе, скажу, что этот проект (надеюсь, что он не будет мертворожденным) посвящен распределенным вычислениям. А какова наша выгода? Прямая. Распределять мы будем взлом хешей. А то сейчас народ идеями о "всеобщем благе" не привлечешь, им конкретную выгоду подавай, причем не в перспективе, а уже сейчас или, в крайнем случае, завтра утром. Выгода будет! Нужно только собраться и написать софтинку. Дело в том, что у меня по реализации взаимодействия с сетью в никсах стоит "3-". А почему именно никсы? Дело в том, что именно здесь мы можем реализовать мультиплатформенность с минимальными затратами. Т.е. оставить сырцы для никсов, а потом портировать все это чудо с помощью cygwin. Но это все прелюдия. А начать написание нужно с концепции и реализации кое-каких узлов будущего продукта.
А концепция уже более-менее прописана на вышеуказанном форуме. Кстати, мы еще ничего толком не решили, только принцип построения очереди более-менее утвержден. Поэтому данный фрагмент кода будет описывать именно очередь.
В нашем случае очередь удобно реализовать как двунаправленный циклический список. Список будет состоять из звеньев с указателями на задание, предыдущее и следующее звено. Класс очереди проще всего унаследовать от класса звена, т.к. в любом случае очередь содержит служебное звено или звено-разделитель.
class TSharedTask;
//декларируем класс задания, т.к. мы будем работать с указателями на экземпляры этого класса
class TSharedLink;
//декларируем класс звена, т.к. мы будем работать с указателями на экземпляры этого класса
define PTSharedTask TSharedTask*;
define PTSharedLink TSharedLink*;
class TSharedLink{
//класс звена в очереди заданий
private:
PTSharedTask pTask;
//указатель на задание
PTSharedLink pPrev;
//указатель на предыдущее звено
PTSharedLink pNext;
//указатель на следующее звено
public:
TSharedLink(void);
~TSharedLink(void);
void SetTask(PTSharedTask pNewTask);
void SetNext(PTSharedLink pNewNext);
void SetPrev(PTSharedLink pNewPrev);
PTSharedTask GetTask(void);
PTSharedLink GetNext(void);
PTSharedLink GetPrev(void);
};
class TSharedQueue:public TSharedLink{
private:
PTSharedLink pFirst;
//указатель на первое звено
PTSharedLink pCurr;
//указатель на текущее звено
public:
TSharedQueue(void);
~TSharedQueue(void);
void SetTask(PTSharedTask pNewTask);
void AddPrevTask(PTSharedTask pNewTask);
void AddNextTask(PTSharedTask pNewTask);
void DelPrevTask();
void DelCurrTask();
void DelNextTask();
void Reset();
void GoNext();
void GoPrev();
PTSharedTask GetTask(void);
};
//Begin of TSharedLink implementation
TSharedLink::TSharedLink(void){
//В принципе, в этом конструкторе ничего не нужно...
}
TSharedLink::~TSharedLink(void){
//А вот тут нужно удалить само задание... Память высвобождать надо.
delete pTask;
}
void TSharedLink::SetTask(PTSharedTask pNewTask){
pTask=pNewTask;
}
void TSharedLink::SetNext(PTSharedLink pNewNext){
pNext=pNewNext;
}
void TSharedLink::SetPrev(PTSharedLink pNewPrev){
pPrev=pNewPrev;
}
PTSharedTask TSharedLink::GetTask(void){
return pTask;
}
PTSharedLink TSharedLink::GetNext(void){
return pNext;
}
PTSharedLink TSharedLink::GetPrev(void){
return pPrev;
}
//End of TSharedLink implementation
//Begin of TSharedQueue implementation
TSharedQueue::TSharedQueue(void){
//Создаем служебное звено и "замыкаем" его на себя
PTSharedTask pFirstTask;
pFirstTask=new TSharedTask();
pFirst=new TSharedLink();
pFirst->pTask=pFirstTask;
pFirst->pPrev=pFirst;
pFirst->pNext=pFirst;
pCurr=pFirst;
}
TSharedQueue::~TSharedQueue(void){
PTSharedLink pTemp;
pCurr=pFirst->pNext;
while(pCurr!=pFirst){
pTemp=pCurr->pNext;
delete pCurr;
pCurr=pTemp;
}
delete pFirst;
}
void TSharedQueue::SetTask(PTSharedTask pNewTask){
pCurr->pTask=pNewTask;
}
void TSharedQueue::AddPrevTask(PTSharedTask pNewTask){
PTSharedLink pTemp,pTemp2;
pTemp=new TSharedLink();
pTemp->pTask=pNewTask;
pTemp2=pCurr->pPrev;
pTemp2->pNext=pTemp;
pCurr->pPrev=pTemp;
}
void TSharedQueue::AddNextTask(PTSharedTask pNewTask){
PTSharedLink pTemp,pTemp2;
pTemp=new TSharedLink();
pTemp->pTask=pNewTask;
pTemp2=pCurr->pNext;
pTemp2->pPrev=pTemp;
pCurr->pNext=pTemp;
}
void TSharedQueue::DelPrevTask(){
PTSharedLink pTemp,pTemp2;
pTemp=pCurr->pPrev;
pTemp2=pTemp->pPrev;
pTemp2->pNext=pCurr;
pCurr->pPrev=pTemp2;
delete pTemp;
}
void TSharedQueue::DelCurrTask(){
PTSharedLink pTemp,pTemp2;
pTemp=pCurr->pPrev;
pTemp2=pCurr->pNext;
pTemp2->pPrev=pTemp;
pTemp->pNext=pTemp2;
delete pCurr;
pCurr=pTemp;
//Тут спорная позиция. Если удаляем текущее задание,
//то новым текущим может стать как предыдущее, так и
//следующее. По умолчанию, поставим предыдущее.
}
void TSharedQueue::DelNextTask(){
PTSharedLink pTemp,pTemp2;
pTemp=pCurr->pNext;
pTemp2=pTemp->pNext;
pTemp2->pPrev=pCurr;
pCurr->pNext=pTemp2;
delete pTemp;
}
void TSharedQueue::Reset(){
pCurr=pFirst;
}
void TSharedQueue::GoNext(){
pCurr=pCurr->pNext;
}
void TSharedQueue::GoPrev(){
pCurr=pCurr->pPrev;
}
PTSharedTask TSharedQueue::GetTask(void){
return pCurr->pTask;
}
//End of TSharedQueue implementation
На этом пока все. Далее будет уместным говорить о классе заданий. Каким он должен быть? Честно говоря, тут появляются первые споры о целесообразности наличия в нем тех или иных полей. Немного расскажу о том, как я вижу его. Класс заданий, по-моему, должен состоять из нескольких частей: служебного поля типа int (для хранения информации о заданиях, там можно будет хранить метку служебного звена, приоритет задания или можно оставить зарезервированным на будущее), непосредственно задания, времени получения задания и дедлайна (deadline, можно заменить его на время действия запроса), крайнего срока обработки задания сервером, описания типа возврата результатов (на e-mail, непосредственно при соединении). Как видишь, работы здесь предостаточно. Поэтому предлагаю тебе напрячь свое серое вещество головного мозга, сгенерировать пару идей и отослать их словесное отображение (желательно так, чтобы я все понял, с ремарками и примерами) на ящик журнала - [email protected].
Жду комментариев. Adieu, mes amis!
|
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |