UfnCod3r
سه شنبه 30 مهر 1392, 09:25 صبح
سلام برفرض من یه کلاس لیست پیوندی دارم که چند تا تابع داره . addNode, getNodeCount, deleteNode
الان هر تابع رو Thred Safe کردم .( با CRITICAL_SECTION ها ) تا موقعی که همزمان چند تا خط یک تابع رو صدا می زنن مشکلی پیش نیاد. ولی مشکل اینه که این توابع من به هم وابسته هستن و مثلا وقتی ی خط داره تابع addNode رو استفاده میکنه ی خط دیگه میاد و DeleteNode رو استفاده می کنه و مشکل پیش میاد.
من می خوام وقتی یکی ازین تابع ها داره کار می کنه بقیه که می خوان توابع دیگه رو استفاده کنن صبر کنه تا کار تابعه تموم بشه .
درواقع هم زمان فقظ یکی ازین توابع باید استفاده بشه .
ی راهش اینه که ی تابع اصلی درست کنم که با یه شرط مشخص بشه کدوم کار رو انجام بده . که به خاطر تفاوت پارامترها و نوع برگشتی متفاوت هر کدومشون خوب در نمیاد .:متفکر:
با مخلوت کردن چند تا while , volatile هم میشه ی کارایی کرد ولی اونم باز خوب نیست .:متفکر:
بهترین راه چیه؟:متفکر:
این شما و این کد ما (بچه ها کد کد بچه ها):لبخند:
Copy Right C UfnCod3r Inc :چشمک::قهقهه:
//////////////////////////////////////////////////////////////////////////Thread Access Control
class TAC
{
CRITICAL_SECTION m_csec;
public:
void init() { ::InitializeCriticalSection(&m_csec); }
void release() { ::DeleteCriticalSection(&m_csec); }
void lock() { ::EnterCriticalSection(&m_csec); }
void unlock() { ::LeaveCriticalSection(&m_csec); }
};
//////////////////////////////////////////////////////////////////////////ForwardList, Thread Safe
template < typename T> class ForwardListTS
{
public:
class Node
{
friend class ForwardListTS;
Node(const T& value) : m_next(nullptr), m_value(value) {}
Node* m_next;
public:
T m_value;
Node* next() const { return m_next; }
};
private:
volatile uintptr m_nodeHead;
Node* m_pLastNode;
mutable TAC m_tac;
public:
ForwardListTS()
{
m_nodeHead = 0;
m_pLastNode = (Node*)&m_nodeHead;
m_tac.init();
}
Node* firstNode() const { return (Node*)m_nodeHead; }
uint nodeCount() const
{
uint n = 0;
Node* iter = firstNode();
m_tac.lock();
while(iter)
{
iter = iter->next();
n++;
}
m_tac.unlock();
return n;
}
Node* push(const T& value)
{
m_tac.lock();
Node* newNode = new Node(value);
m_pLastNode->m_next = newNode;
m_pLastNode = newNode;
m_tac.unlock();
return newNode;
}
bool deleteNode(Node* node)
{
if(node == nullptr) return false;
m_tac.lock();
Node* iter = (Node*)m_nodeHead;
Node* iterPre = (Node*)&m_nodeHead;
while (iter)
{
if(iter == node)
{
if(iter == m_pLastNode)
m_pLastNode = iterPre;
iterPre->m_next = iter->m_next;
delete iter;
return true;
}
iterPre = iter;
iter = iter->next();
}
m_tac.unlock();
return false;
}
Node* operator [] (size_t i) const
{
m_tac.lock();
Node* iter = firstNode();
//while (iter && i) // TEST, JNZ, TEST, JNZ,
while (((uintptr)iter) * i) //avoiding branch MUL, TEST, JNZ
{
iter = iter->next();
i--;
}
m_tac.unlock();
return iter;
}
}
:شیطان::شیطان::شیطان:
الان هر تابع رو Thred Safe کردم .( با CRITICAL_SECTION ها ) تا موقعی که همزمان چند تا خط یک تابع رو صدا می زنن مشکلی پیش نیاد. ولی مشکل اینه که این توابع من به هم وابسته هستن و مثلا وقتی ی خط داره تابع addNode رو استفاده میکنه ی خط دیگه میاد و DeleteNode رو استفاده می کنه و مشکل پیش میاد.
من می خوام وقتی یکی ازین تابع ها داره کار می کنه بقیه که می خوان توابع دیگه رو استفاده کنن صبر کنه تا کار تابعه تموم بشه .
درواقع هم زمان فقظ یکی ازین توابع باید استفاده بشه .
ی راهش اینه که ی تابع اصلی درست کنم که با یه شرط مشخص بشه کدوم کار رو انجام بده . که به خاطر تفاوت پارامترها و نوع برگشتی متفاوت هر کدومشون خوب در نمیاد .:متفکر:
با مخلوت کردن چند تا while , volatile هم میشه ی کارایی کرد ولی اونم باز خوب نیست .:متفکر:
بهترین راه چیه؟:متفکر:
این شما و این کد ما (بچه ها کد کد بچه ها):لبخند:
Copy Right C UfnCod3r Inc :چشمک::قهقهه:
//////////////////////////////////////////////////////////////////////////Thread Access Control
class TAC
{
CRITICAL_SECTION m_csec;
public:
void init() { ::InitializeCriticalSection(&m_csec); }
void release() { ::DeleteCriticalSection(&m_csec); }
void lock() { ::EnterCriticalSection(&m_csec); }
void unlock() { ::LeaveCriticalSection(&m_csec); }
};
//////////////////////////////////////////////////////////////////////////ForwardList, Thread Safe
template < typename T> class ForwardListTS
{
public:
class Node
{
friend class ForwardListTS;
Node(const T& value) : m_next(nullptr), m_value(value) {}
Node* m_next;
public:
T m_value;
Node* next() const { return m_next; }
};
private:
volatile uintptr m_nodeHead;
Node* m_pLastNode;
mutable TAC m_tac;
public:
ForwardListTS()
{
m_nodeHead = 0;
m_pLastNode = (Node*)&m_nodeHead;
m_tac.init();
}
Node* firstNode() const { return (Node*)m_nodeHead; }
uint nodeCount() const
{
uint n = 0;
Node* iter = firstNode();
m_tac.lock();
while(iter)
{
iter = iter->next();
n++;
}
m_tac.unlock();
return n;
}
Node* push(const T& value)
{
m_tac.lock();
Node* newNode = new Node(value);
m_pLastNode->m_next = newNode;
m_pLastNode = newNode;
m_tac.unlock();
return newNode;
}
bool deleteNode(Node* node)
{
if(node == nullptr) return false;
m_tac.lock();
Node* iter = (Node*)m_nodeHead;
Node* iterPre = (Node*)&m_nodeHead;
while (iter)
{
if(iter == node)
{
if(iter == m_pLastNode)
m_pLastNode = iterPre;
iterPre->m_next = iter->m_next;
delete iter;
return true;
}
iterPre = iter;
iter = iter->next();
}
m_tac.unlock();
return false;
}
Node* operator [] (size_t i) const
{
m_tac.lock();
Node* iter = firstNode();
//while (iter && i) // TEST, JNZ, TEST, JNZ,
while (((uintptr)iter) * i) //avoiding branch MUL, TEST, JNZ
{
iter = iter->next();
i--;
}
m_tac.unlock();
return iter;
}
}
:شیطان::شیطان::شیطان: