饭中淹的避难所~~~~~

偶尔来避难的地方~

  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  94 随笔 :: 0 文章 :: 257 评论 :: 0 Trackbacks
共3页: 1 2 3 
@cpm
另外,我准备用barrier来代替volatile,从而让所有的读写操作都能够被优化,并且,还能够获得及时的更新。
@cpm
在这里,我说的是个多线程通信问题,它的单个任务是线性的。
我认为:

所有的多线程问题都可以细分为单个线性任务。

不能细分为线性任务的问题,是不存在的。

锁是不可避免的,就算是状态也是一种锁。

这里的无锁,就是不用系统提供的锁。

无论是什么多线程问题,锁都是保证线性任务线性执行的。

所以没有你说的不能简化为单线程的问题。

@cpm
代码中的赋值是在一起的,而且是对不同的变量,所以他们可能会被乱序执行。这样另一个线程获取到通过状态后,可能这时候其他的写操作还没有执行完。就会出问题。

所以在修改状态前,要用一个写barrier来过滤掉其他写操作的reorder,从而实现修改状态时,所有写操作都完成。


另外,关于例程的代码,只是做分析用。实际使用时,还是得用一些手段来让系统对线程进行调度。这个是最基本的常识。
@shbooom
不是locked,是dosomething.
线程A
if(doSomething==true) { DoSomething(); doSomething=false;}

线程B
if(doSomething==false) { DoOtherthing(); doSomething=true;}

在A线程DoSomething()时,B线程进不去判断,所以不会用DoOtherthing()来干扰。

或者就按照你的locked
修改成这样
线程A
if(locked==false) { doSomething(); locked=true;}
线程B
if(locked) { doOtherthing(); locked = false;}

在A的花括号内,B的doOtherthing不会影响A的doSomething。





@fcc
确实是存在这种情况。
@shbooom
如果不考虑优化,还是可以用的,这个方法。

@Kevin Lynx
p的地址大于a。
所以a在栈顶,p在a下面。还有个push ebp,接下来就是返回地址。
正好三个。
re: 无锁线程通信(1) 饭中淹 2010-05-06 15:13
@cppexplore
本篇文章序号(1)
1- CALL会把下一个指令的地址放进堆栈。
2- RET就让这个地址出栈,并跳转至这个地址。
3- 局部变量也是在栈上的。

代码中,你用局部变量的地址定位到栈内的ret返回地址,然后将其修改为TEST的函数地址。RET后,就跳转到TEST函数了。因为没有CALL,所以栈内不会压入返回地址,然后栈就乱掉了,后面依赖栈的指令,就可能会导致出错。

在一些软件保护里面,经常会用到这种手段,PUSH FUNCPTR, RET。这样可以用CALL来调用函数。从而迷惑分析者。通过ESP寄存器直接操作,更让分析者头大。再用一些无效指令插在其中,做成花指令,就更高端了。特别是花连跳,分析者就很难一眼分辨出走向了。

re: 无锁线程通信(1) 饭中淹 2010-05-06 12:13
@爱饭盒
请你认真看清楚,我就不解释了。
re: 无锁线程通信(1) 饭中淹 2010-05-06 10:32
@fcc
无锁编程确实没有这么简单。
这个例子,你仔细看每一句话,其实说的是你第二种方法。也就是互相等待的方法。低效是肯定的。
这个是第一部分,从简单的开始说起,慢慢的深入进去。
@陈梓瀚(vczh)
是的。
我这里描述的就是服务器在更新物件是否显示时,对大物件的处理。实际上物件的资源都在客户端。服务器只是让客户端显示或者不显示而已。
后面说的,关于客户端和服务器端在结构上的统一,是可以实现一个交互性更强的世界。比如一个完全由星球和飞船组成的世界。各部分都在靠近或者远离。
@陈昱(CY)
是的,是服务器传给客户端显示的物体。
单足,就是只用一组坐标进行可见性检查。
多足,就是有多组坐标用于可见性的检查,只要一组坐标在可见范围内,就认为是可见。
re: 无锁线程通信(1) 饭中淹 2010-05-05 21:05
@shbooom
不会,这是绝对安全的。
检查成功后,置位权就在自己手中了,所以不存在不安全的情况。
@陈昱(CY)
你没看明白。。。。
@金庆
列舉過程消耗太大。
re: 用于UI系统中的脚本接口 饭中淹 2010-04-28 19:37
@ccsdu2009
是的。
但是这个是脚本系统接口,用来处理UI事件的。实现UI和主程序之间的粘合。
我一般會用一種類似工廠的方法。

class CPeople
{

int m_iAge;

CPeople() : m_iAge(-1) {}
~CPeople() {}
bool _Init( int iAge )
{
if( iAge <= 0 || iAge > 200 )return false;
m_iAge = iAge;
return true;
}
public:
static CPeople * Create( int iAge )
{
CPeople * people = new CPeople();
if( people != NULL &&
!people->_Init(iAge) )
{
people->Release();
people = NULL;
}
return people;
}
void Release() { delete this;}
};


私有的構造函數和西狗函數確保他們不能被單獨分配和刪除
所有的途徑只有create和release。

re: WOF(名将三国)的TGL文件格式 饭中淹 2010-02-21 17:37
@菜鸟
使用ZLIB解压
@金庆
局域网内还是可以的。
怎么开始像C ++ BUILDER了= =
re: 服务器程序运行时逻辑替换 饭中淹 2010-02-15 17:41
@金庆
我是以对象为单位的替换。只要接口不修改,以及状态拷贝正确,替换还是很简单的。
@驯鹿
那要知道各个字段的意思了,有些字段需要逆向才行。
不想去破解那么深入。能看到图就好了。
re: WOF(名将三国)的TGL文件格式 饭中淹 2010-01-27 08:28
@求助
如果要逆向就不破了,那是违反用户协议的
re: WOF(名将三国)的TGL文件格式 饭中淹 2010-01-25 17:53
@Kevin Lynx
有使用方法- -
你看漏了
re: WOF(名将三国)的TGL文件格式 饭中淹 2010-01-25 13:45
下期预告:WOF(名将三国)MOTIONDATA中的PKX文件的解析
new分配的在堆里,你溢出了,只会导致堆出问题。而你下面又没有再使用堆,所以不会出错。
直接写的局部变量,分配在堆栈里,堆栈里有函数的返回地址,所以溢出了,覆盖了返回地址,函数执行完就出错了。
另外,有些 编译器会生成对固定长度数组的保护性检测代码,一旦溢出,就会弹出提示。早先在vs2003还是vs2002的时候见过。
很好!!!!!!!!!
@oldtom
暂时不开,未来会开
re: Autotools初体验 饭中淹 2009-12-24 10:31
这个相对于IDE来说,有什么优势?
re: 二分查找学习札记 饭中淹 2009-10-09 10:07
查找i*10的结果是:

t1 = 1159
t2 = 1160
t3 = 1515

你的算法的消耗时间仍然多几百毫秒

re: 二分查找学习札记 饭中淹 2009-10-09 10:03
@那谁
我是这样测试的,不知道有么有错。
第一步:将你的算法嵌入到我的binarysearch里面
static inline int _search( const T1 * pTArray, int nArraySize, const T2 & v, int & insertpoint )
{
if( pTArray == NULL )
{
insertpoint = 0;
return -1;
}

int left, right, middle;

left = -1, right = nArraySize;

while (left + 1 != right)
{
middle = left + (right-left) / 2;

if (_cmp( pTArray[middle], v ) < 0)
{
left = middle;
}
else
{
right = middle;
}
}

if (right >= nArraySize || _cmp( pTArray[right], v ) != 0)
{
right = -1;
}

return right;
//}

}
第二步:测试函数
#define MAX_DATA_COUNT 100000
int gDatas[MAX_DATA_COUNT];
#define MAX_FIND_DATA_COUNT 10000
int gFindDatas[MAX_FIND_DATA_COUNT];
#define MAX_TEST_TIMES 1000
void Test1()
{
typedef xbinary_search<int, int> INT_SEARCH;
for( int t = 0;t < MAX_TEST_TIMES; ++t )
{
for( int i = 0;i < MAX_FIND_DATA_COUNT; ++i )
{
int nPos = INT_SEARCH::search_value( gDatas, MAX_DATA_COUNT, gFindDatas[i] );
if( nPos != gFindDatas[i] )printf( "error !\n" );
}
}
}

void Test2()
{
typedef xbinary_search2<int, int> INT_SEARCH;
for( int t = 0;t < MAX_TEST_TIMES; ++t )
{
for( int i = 0;i < MAX_FIND_DATA_COUNT; ++i )
{
int nPos = INT_SEARCH::search_value( gDatas, MAX_DATA_COUNT, gFindDatas[i] );
if( nPos != gFindDatas[i] )printf( "error !\n" );
}
}
}

void Test3()
{
typedef xbinary_search3<int, int> INT_SEARCH;
for( int t = 0;t < MAX_TEST_TIMES; ++t )
{
for( int i = 0;i < MAX_FIND_DATA_COUNT; ++i )
{
int nPos = INT_SEARCH::search_value( gDatas, MAX_DATA_COUNT, gFindDatas[i] );
if( nPos != gFindDatas[i] )printf( "error !\n" );
}
}
}

xbinary_search3就是你的函数嵌入的

第三步:数据生成和测试代码
srand( 312431 );
for( int i = 0;i < MAX_DATA_COUNT; ++i )
{
gDatas[i] = i;
}

for( int i = 0;i < MAX_FIND_DATA_COUNT; ++i )
{
gFindDatas[i] = (rand() % 10000) * MAX_DATA_COUNT / 10000;
}
timeBeginPeriod(1);
DWORD dwT1 = timeGetTime();
Test1();
dwT1 = timeGetTime() - dwT1;
printf( "t1 = %u\n", dwT1 );
DWORD dwT2 = timeGetTime();
Test2();
dwT2 = timeGetTime() - dwT2;
printf( "t2 = %u\n", dwT2 );
DWORD dwT3 = timeGetTime();
Test3();
dwT3 = timeGetTime() - dwT3;
printf( "t3 = %u\n", dwT3 );
timeEndPeriod(1);

最后结果


t1 = 1828
t2 = 1822
t3 = 2155


re: 二分查找学习札记 饭中淹 2009-10-08 07:51
@那谁
大量随机数值的查找。
用我自己的二分算法和最后的算法进行比较测试。

结果是最后的算法比我的算法慢个几百毫秒。

是10万int数组,1万预生成的待查数据。

重复1000次后得出的时间。
我的算法大概是1.8S
你文中的算法是2.XS
RELEASE版,在2.6GHZ的INTEL CPU上。

为了排除缓冲区干扰等,我用自己的算法的变种进行过测试,相差不到10毫秒。



re: 二分查找学习札记 饭中淹 2009-10-07 10:31
测试了下。。。。最后的代码效率不高。
re: 基类角色之对象管理器 饭中淹 2009-07-03 10:18
@李现民
确实是类似观察者这种,不过更直接了
re: 基类角色之对象管理器 饭中淹 2009-07-03 10:16
@Kevin Lynx
跟这个差不多。不过不用继承

xLink<Host, Target>


xLink.link( xLink<Target, Host> & lnk );
xLink.disLinkAll();

*
&
是重载的。
返回Host
re: 基类角色之对象管理器 饭中淹 2009-07-02 15:20
我一般是用一个ID管理器来解决这个问题。
采用直接索引的办法。对于重复的ID使用一个顺序增加的KEY来做验证。

也就是一个ID,一个KEY来索引一个对象。

之前还有一个方法,就是采用一种LINK对象,LINK对象能链接到另外一个LINK对象,并互换HOST指针,并且有主从关系的LINK方式。
当一个LINK对象销毁的时候,会通知所有已经连接的LINK对象放弃自己的HOST指针。这样的话,别的对象里面保存的指针会随着原始对象的销毁而自动清空。
用小方格子来拼成六边形,然后通过查表方式来进行坐标转换。
@陈梓瀚(vczh)
有眉目了!
OFFICEXP之后,MS出了个叫做TEXT SERVICE FRAMEWORK的东西。而微软拼音就是用这个TSF开发的。要完美支持微软拼音就需要用这个东西来对输入法进行操作。
研究TSF中。。。。
re: Charlib更新Vector和Matrix... 饭中淹 2009-03-10 13:28
超市特工。。。。
re: 重载分配符. 饭中淹 2009-03-02 16:43
玩。。。。。。
re: 带括号浮点型计算器final 饭中淹 2009-02-19 09:11
不用争取了,你已经是了.
这个,太简陋了,就是一些字体相关的东西...
看看API帮助就会写了.
你可以测试下,在不同的cpp里面输出这个变量的地址,就什么都清楚了。

re: 能用于 VC6 的 CImage 类 饭中淹 2009-01-08 17:18
用VC6的理由有点牵强。。。
re: 面试在华为 饭中淹 2008-12-18 18:16
他们估计是去掉最好的,去掉最差的,保留中间的。
这个有什么优势?
可以用保护线程
把崩溃的信息记录下来,顺便把未保存的数据保存下
re: 文件夹比较备份工具 饭中淹 2008-11-07 09:14
博主的意思是不比较文件名,直接用md5互相比较,找出某一方没有,而另一方有的md5。这样就算修改了名字也不会有问题。

不过有一个问题需要考虑,如何避免垃圾文件,比如一方修改了名字也修改了内容的。这样同样意义的文件就出现了两个。


做一个功能
直接打
/名字 内容
就可以给好友发送消息

不管他是gtalk的,msn的,还是qq的
共3页: 1 2 3