能力值:
( LV6,RANK:90 )
能力值:
( LV6,RANK:90 )
能力值:
( LV6,RANK:90 )
[求助]SetThreadContext异常处理
测试发现,AddVectoredExceptionHandler 是有效的。 但是在异常处理函数中我没法处理掉这个异常。
There are no more endpoints available from the endpoint mapper
不知道操作系统是怎么处理掉的。
能力值:
( LV6,RANK:90 )
能力值:
( LV6,RANK:90 )
能力值:
( LV6,RANK:90 )
[原创]一种多线程基于计数无锁实现
看了大家的评论,这种技术确实有诸多局限性,但是只要在实际中帮助解决一些问题,那他还是有用的。下面贴一个支持一个线程读,一个线程写的CycleBuffer,注意该CycleBuffer没有经过实际测试。
class ZwAsynCount
{
public:
ZwAsynCount(unsigned uSize) //uSize必须为2的n次方
{
m_uReadCount = 0;
m_uWriteCount = 0;
m_uSize = uSize;
}
int Write(int nLen) //返回元素位置 -1表示读失败
{
int nRet = -1;
if (GetFree() >= nLen)
{
nRet = m_uWriteCount&(m_uSize-1);
}
return nRet;
}
void AddWrite(int nCount = 1)
{
m_uWriteCount += nCount;
}
int GetUsed()
{
return m_uWriteCount - m_uReadCount;
}
int GetFree()
{
return m_uSize - GetUsed();
}
int Read(int nLen) //返回元素位置 -1表示写失败
{
int nRet = -1;
if (GetUsed() <= nLen)
{
nRet = m_uReadCount&(m_uSize-1);
}
return nRet;
}
void AddRead(int nCount = 1)
{
m_uReadCount+= nCount;
}
private:
unsigned m_uSize;
volatile unsigned m_uReadCount;
volatile unsigned m_uWriteCount;
};
class CCycleBuffer
{
public:
CCycleBuffer(int nSize):m_asynCount(nSize)
{
m_pBuf = new char[nSize];
m_nTalLen = nSize;
}
int GetFreeSpace()
{
return m_asynCount.GetFree();
}
int GetLength()
{
return m_asynCount.GetUsed();
}
~CCycleBuffer()
{
if (m_pBuf)
{
delete m_pBuf;
}
}
bool Write(char* buf, int count)
{
bool bRet = false;
int nPos = m_asynCount.Write(count);
if (nPos >=0)
{
if (m_nTalLen - nPos >= count)
{
memcpy(m_pBuf + nPos, buf, count);
}
else
{
memcpy(m_pBuf + nPos, buf, m_nTalLen - nPos);
memcpy(m_pBuf, buf + m_nTalLen - nPos, count - (m_nTalLen - nPos));
}
m_asynCount.AddWrite(count);
bRet = true;
}
return bRet;
}
bool Read(char* buf, int count)
{
bool bRet = false;
int nPos = m_asynCount.Read(count);
if (nPos >=0)
{
if (m_nTalLen - nPos >= count)
{
memcpy(buf,m_pBuf + nPos,count);
}
else
{
memcpy(buf,m_pBuf + nPos, m_nTalLen - nPos);
memcpy(buf + m_nTalLen - nPos,m_pBuf, count - (m_nTalLen - nPos));
}
m_asynCount.AddRead(count);
bRet = true;
}
return bRet;
}
private:
char *m_pBuf;
int m_nTalLen;
ZwAsynCount m_asynCount;
};
能力值:
( LV6,RANK:90 )
[原创]一种多线程基于计数无锁实现
相对于环形缓冲:
读线程读取一个元素,需要修改count计数,修改count计数是需要加锁。
写线程写入一个元素,需要修改count计数,修改count计数是需要加锁。
该方法的最大优点是不加锁,不使用原子操作实现了count计数。
如果多线程同时读的话,是需要加锁的。多线程同时写,也是需要加锁的。
能力值:
( LV6,RANK:90 )
能力值:
( LV6,RANK:90 )
能力值:
( LV6,RANK:90 )
能力值:
( LV6,RANK:90 )
能力值:
( LV6,RANK:90 )
[原创]利用Thunk技术改写窗口类回调函数例子
1.由于建立项目时疏忽,把TestThunk建成了TestTrunk给大家带来阅读不便,请谅解。
2.由于工作后很少研究底层东西了,除了在COM里面看到一些关于stub。在网上看到Thunk,姑且当做thunk吧。
看到论坛里帖子
http://bbs.pediy.com/showthread.php?t=76213&highlight= 发现可以只用一个静态函数实现窗口类回调函数变为非静态成员函数。主要是在
LRESULT CALLBACK CMyWindow::TempWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if (message == WM_CREATE)//此处使用WM_NCCREATE消息也可以
{
//提取出对象指针
CMyWindow *w = NULL;
w = (CMyWindow*)((LPCREATESTRUCT)lParam)->lpCreateParams;
w->_hwnd = hWnd;
[COLOR="Red"] //在此直接使用非静态成员函数,this指针通过ecx传递。[/COLOR]
void* pProc = w->m_PorcA.Thiscall(w, Thunk::GetMemberFxnAddr(&CMyWindow::WndProc));
SetWindowLong(hWnd, GWL_WNDPROC, (LONG)pProc);
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
做以上更改。
在此感谢zhangludu,这份代码中使用了他写的的thunk类,真的很好用。以前一直在想着怎样使用thunk实现非静态成员函数作为线程函数,没想到他早就实现了。希望大家继续多提意见,
。