@cpm
另外,我準備用barrier來代替volatile,從而讓所有的讀寫操作都能夠被優化,并且,還能夠獲得及時的更新。
@cpm
在這里,我說的是個多線程通信問題,它的單個任務是線性的。
我認為:
所有的多線程問題都可以細分為單個線性任務。
不能細分為線性任務的問題,是不存在的。
鎖是不可避免的,就算是狀態也是一種鎖。
這里的無鎖,就是不用系統提供的鎖。
無論是什么多線程問題,鎖都是保證線性任務線性執行的。
所以沒有你說的不能簡化為單線程的問題。
@cpm
代碼中的賦值是在一起的,而且是對不同的變量,所以他們可能會被亂序執行。這樣另一個線程獲取到通過狀態后,可能這時候其他的寫操作還沒有執行完。就會出問題。
所以在修改狀態前,要用一個寫barrier來過濾掉其他寫操作的reorder,從而實現修改狀態時,所有寫操作都完成。
另外,關于例程的代碼,只是做分析用。實際使用時,還是得用一些手段來讓系統對線程進行調度。這個是最基本的常識。
re: 無鎖多線程通信(0):回到起點 飯中淹 2010-05-06 18:36
@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。
re: 無鎖線程通信(2):例程與分析 飯中淹 2010-05-06 16:42
@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
不會,這是絕對安全的。
檢查成功后,置位權就在自己手中了,所以不存在不安全的情況。
re: 用于UI系統中的腳本接口 飯中淹 2010-04-28 19:37
@ccsdu2009
是的。
但是這個是腳本系統接口,用來處理UI事件的。實現UI和主程序之間的粘合。
re: 設計的兩難:選擇異常還是兩段構造 飯中淹 2010-03-05 08:34
我一般會用一種類似工廠的方法。
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解壓
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的時候見過。
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 14:58
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指針。這樣的話,別的對象里面保存的指針會隨著原始對象的銷毀而自動清空。
用小方格子來拼成六邊形,然后通過查表方式來進行坐標轉換。
re: 微軟拼音輸入法的XX。。。。 飯中淹 2009-03-17 02:22
@陳梓瀚(vczh)
有眉目了!
OFFICEXP之后,MS出了個叫做TEXT SERVICE FRAMEWORK的東西。而微軟拼音就是用這個TSF開發的。要完美支持微軟拼音就需要用這個東西來對輸入法進行操作。
研究TSF中。。。。
re: 重載分配符. 飯中淹 2009-03-02 16:43
玩。。。。。。
re: 帶括號浮點型計算器final 飯中淹 2009-02-19 09:11
不用爭取了,你已經是了.
這個,太簡陋了,就是一些字體相關的東西...
看看API幫助就會寫了.
你可以測試下,在不同的cpp里面輸出這個變量的地址,就什么都清楚了。
re: 面試在華為 飯中淹 2008-12-18 18:16
他們估計是去掉最好的,去掉最差的,保留中間的。
re: 崩潰后重啟,用共享內存恢復你的數據 飯中淹 2008-11-13 15:22
可以用保護線程
把崩潰的信息記錄下來,順便把未保存的數據保存下
re: 文件夾比較備份工具 飯中淹 2008-11-07 09:14
博主的意思是不比較文件名,直接用md5互相比較,找出某一方沒有,而另一方有的md5。這樣就算修改了名字也不會有問題。
不過有一個問題需要考慮,如何避免垃圾文件,比如一方修改了名字也修改了內容的。這樣同樣意義的文件就出現了兩個。
做一個功能
直接打
/名字 內容
就可以給好友發送消息
不管他是gtalk的,msn的,還是qq的