• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            loop_in_codes

            低調做技術__歡迎移步我的獨立博客 codemaro.com 微博 kevinlynx

            共6頁: 1 2 3 4 5 6 
            我覺得,用你這個類與普通的enum相比,更多時候我們需要的是一個方便的enum,即使它沒有你這個class安全;
            如果我沒弄錯的話,你這個類雖然sizeof為sizeof(int),但這并不是你所說的“同時也沒有占用任何額外的空間”,因為還有很多static常量。
            @陳梓瀚(vczh)
            就我所查閱的文檔來看,似乎沒有。coroutine.yiled/resume可能算是吧。
            @eXile
            我亦覺得,樓主局限于native win32的思維方式。在對消息的處理上,遵從的是WIN32的消息機制。

            不過從代碼看來(LRESULT之類),這個框架可能沒有考慮跨平臺特性。所以停留在WINDOWS上也沒什么。

            個人拙見。:)
            @francis
            thread2沒有獲得CPU權!thread2沒有被調度!
            這里的用法完全是條件變量的標準用法,如果你硬是要從理論上認為它有問題,那你可以去查條件變量相關資料。這里的結構和條件變量通用用法一樣。你甚至可以找本操作系統書,在上面找到條件變量的使用結構。你想推翻這一切?建議你大量查閱條件變量相關資料。如果你還認為有問題,你應該去對發明條件變量的某個可能已經死掉的牛人說:你這個條件變量的結構有問題。
            @francis
            我讀了幾遍你的這次回復,希望我沒有誤解你的意思:
            thread1被激活,取數據,就可能導致container的size為0,一旦size為0,thread3繼續push的時候就可能會激活thread2。如果OS一直沒有調度到thread2,那么,container就可能經歷過多次size為0,size不為0,也就是thread1和thread3發生多次數據交互。thread2看起來是慘了,因為container曾經有數據,但是thread2卻沒取到?為什么呢?thread2根本沒被OS調度到,從沒有獲取到CPU控制權,它又有什么理由不wait?

            歸根結底,你說的這個問題,只是因為thread2沒有被調度到而已。
            @francis
            詳述下這種會出現問題的情況。如果可以模擬出現的話,麻煩基于multi_list這個類制造這種情況。
            @francis
            while( _container.size() == 0 ) _condition.wait();
            僅當為空的情況下才wait的。代碼在邏輯上不存在大問題,因為這個基礎部件已經被用于實際項目(用于保存驗證服務器端的驗證帳號)。
            @francis
            我們看一次常規的同步操作:
            push_front()
            {
            guard<mutex_type> g(_mutex );
            ...
            }

            pop_front()
            {
            guadr<mutex_type> g(_mutex );
            ...
            }

            那么,在消費者線程里可能會不斷地去檢查隊列大小是否為0(size操作同樣會涉及到同步),
            這浪費了CPU資源。而如果:
            pop_front()
            {
            guadr<mutex_type> g(_mutex );
            while( size == 0 ) _cond.wait();
            }
            當大小為0時,wait操作將阻塞此線程,從而讓出了CPU資源(wait會阻塞)。

            另一方面,如果每次push操作都進行條件變量的signal,這個所謂的原語操作開銷有多大?
            查看condition::signal/wait代碼,其內部還存在一個_wait_count的同步。另外,如果
            每次push都signal的話,那么pop操作也需要進行wait,這樣以來它其實已經不是條件變量,
            而是信號量了。

            我們所要的效果,就是在隊列元素為0時,進行pop操作的時候讓其阻塞而已。


            @francis
            關鍵在于,signal和wait會對外部mutex做操作。參見kl_condition.h相關代碼。
            @francis
            你可以查找‘條件變量’(condition variable)的相關資料。
            signal只在隊列尺寸為0時的push操作中調用,因為在pop中會在隊列尺寸為0時wait.
            re: 實現自己的http server Kevin Lynx 2008-08-01 16:08
            @Strive
            很巧, 我恰好看過這個網站,感覺是個少年天才的主頁。之前搜索QQ協議,發現的。還下了他寫的QQ客戶端,不過有問題,我登陸Q后,就被T了。
            re: 實現自己的http server Kevin Lynx 2008-07-31 08:56
            @zx
            高并發數不見得要使用async(不明白你所謂的Async模式是什么?我假設是異步IO),也不見得要使用Overlapped IO (我也不明白你說的"IO的overlapped",我假設是windows下的Overlapped IO),一個event-driven的網路模型就很不錯了。

            @x-matrix
            本文的重點在于對HTTP協議的解析,而不是開發高并發網絡框架。:)
            longshanks終于又發文了。學習。
            @happyday
            取元素只是從樹根取,取了后需要對整棵樹進行調整。
            插入元素插入到最下最右的節點,插入后需要進行微小的調整。
            總之元素的增加/減少,都需要重新調整整棵樹使其依然為一個堆。
            re: 日志該怎么記錄? Kevin Lynx 2008-07-18 10:48
            越來越寫得水了。

            @true
            那就應該沒問題了。‘應用程序初始化失敗’,你用的是VS2005吧?那就跟BOOST沒關系了。新的問題跟項目設定有關系。具體搜索下網絡吧。:)
            我以前編譯ASIO例子程序的時候,就顯示地忽略了以下兩個庫:
            libboost_date_time-vc80-mt-gd-1_34_1.lib
            libboost_regex-vc80-mt-gd-1_34_1.lib
            但是,libboost_system-vc80-mt-gd-1_35.lib則沒遇到過,你顯示地忽略掉看下如何?
            re: VS2005編譯libevent Kevin Lynx 2008-07-07 12:53
            libevent在windows下似乎沒多大實用價值(因為用的是select)。spserver的作者寫了個IOCP版本。
            貌似是有這樣的現象,例如libevent的VC6工程文件用RAR解開后就是壞的。
            re: GameRes里面某位大師的語錄 Kevin Lynx 2008-06-26 21:51
            ‘游戲之家站長’的故事源遠流長。。。
            偶然發現LZ博客有我以前CSDN的鏈接,呵呵,現在我換到CPPBLOG來了,更新下鏈接吧。
            @飯中淹
            前面我說了,condition和guard使用的是同一個mutex,在condition的wait里,會先_external_mutex.release();,然后push的時候,就不會阻塞在guard那里,于是condition.signal(元素為0時,看下代碼),然后pop里的condition.wait就過了。
            @飯中淹
            不會的,condition和guard使用的都是同一個mutex。guard用于一般的同步,condition用于隊列元素為0時的臨界條件。
            @true
            事實上是我寫的. :D 我寫著玩,但是被用到我們的產品里。
            比較有意思的:

            /// my fucking and ugly sorted queue only for ServerInfo struct, because i want
            /// everytime i push_back an element in the queue, it will update the element
            /// which _ls_id && _ws_id && _gs_id already existes.I adapted this queue so that
            /// it can be used in my multi_list. :D I'm a such programmer
            template <typename _Tp, typename _AllocType = std::allocator<_Tp> >
            class my_fucking_list;

            /// partial version for ServerInfo
            template <typename _AllocType>
            class my_fucking_list<ServerInfo, _AllocType>
            {
            public:
            @true
            貌似你誤解我意思了;)

            ’阻塞時不能退出‘:
            例如線程里 WaitFor...INFINITE了,那么它就無法處理消息,也無法判斷退出標志變量,代碼卡在這里了。

            ’他更及時,不用參與排隊‘:
            這個跟上面不是說的同一個問題,隊列是用于實際業務處理,例如寫日志,上面那個說的是線程。

            有道理,對于用struct寫文件這種情況,很容易因為struct的字節對齊問題導致想不到的BUG。尤其是采用直接將struct以二進制方式寫入文件的方式寫文件。
            re: SGI STL的內存池 Kevin Lynx 2008-06-15 09:40
            @Gohan
            rebind可以讓allocator<Tp>的保存者分配其他類型的內存。例如,當實例化list時(例如list<int,my_allocator<int> > ),在list內部就保存著一個my_allocator<int>,但是list需要為自己分配list_node,就是說它需要另一個allocator,那么這個時候就可以通過rebind來完成。
            re: SGI STL的內存池 Kevin Lynx 2008-06-13 12:36
            @關中刀客
            STL默認那個內存池。。。STL默認沒內存池。SGI的STL里那個內存池不是標準的。VC下的STL就沒這個。
            re: (C++)一個愚蠢的錯誤 Kevin Lynx 2008-06-07 09:27
            錯誤就是 memset( ...string ) ?

            有點巧,我同事也犯過這個錯。:D
            @關中刀客
            難道不開源?不知道能否分享下代碼。

            我之前在google,baidu都搜索過你這個東西,沒有發現類似googlecode之類的項目地址。。
            re: IRR的效果圖 Kevin Lynx 2008-06-06 16:21
            @true
            這些是irrlicht引擎的DEMO圖
            @關中刀客
            傳說哥們和我同年同月差一天就同日生(我10號:d)

            還有,一直想看下你的cobra是個什么東西
            re: 寫了個簡單的聊天服務器 Kevin Lynx 2008-06-06 10:59
            @jigloo
            "網絡層用reactor模式封裝異步IO" 似乎proactor才是用于封裝異步IO的吧?

            關于你提出的這幾層封裝,不知道是否可以提供個簡單的整體類圖?不甚感激。
            日志對于一個系統來說確實是必不可少的基礎模塊。
            我用模板寫了個不依賴于具體‘寫’的日志類,簡單的日志等級過濾。
            ///
            /// @file kl_logger.h
            /// @author Kevin Lynx
            /// @date 4.21.2008
            ///
            #ifndef ___KL_LOGGER_H_
            #define ___KL_LOGGER_H_

            #include <assert.h>
            #include <stdarg.h>
            #include <time.h>
            #include <fstream>
            #include "kl_compiler_cfg.h"

            KL_COMMON_NAMESPACE_BEGIN

            /// log level
            enum log_level
            {
            LL_MIN = -1,
            LL_ERROR,
            LL_WARNING,
            LL_INFO,
            LL_DEBUG,
            LL_MAX
            };

            ///
            /// default log pre-string, add system time and log level.
            ///
            struct default_log_prestr
            {
            /// output pre-string in the buffer
            /// @return the offset of the buf.
            std::size_t operator() ( char *buf, int level )
            {
            char time[9];
            char date[9];
            _strtime( time );
            _strdate( date );

            const char *ll_desc = 0;
            switch( level )
            {
            case LL_ERROR:
            ll_desc = "ERROR";
            break;
            case LL_WARNING:
            ll_desc = "WARNING";
            break;
            case LL_INFO:
            ll_desc = "INFO";
            break;
            case LL_DEBUG:
            ll_desc = "DEBUG";
            break;

            default:
            ll_desc = "UNKNOWN";
            }

            // combine
            sprintf( buf, "%s %s %s : ", date, time, ll_desc );
            return strlen( buf ) ;
            }
            };

            ///
            ///
            /// A simple logger class to write log information.
            ///
            /// @param _Output where the log information to put, it must implement 'log( const char*)' function.
            /// @param _PreStr used to write the pre-string of the log text like : 4.21.2008 : something.
            /// @param string_size used when format string.(static buffer is more fast than dynamic buffer)
            template <typename _Output, typename _PreStr = default_log_prestr, std::size_t _string_size = 1024>
            class logger
            {
            public:
            /// output object type
            typedef _Output output_type;

            /// pre-string type
            typedef _PreStr prestr_type;

            /// string size used when formatting strings.
            enum
            {
            string_size = _string_size
            };

            public:
            /// constructor
            logger() :
            _output( 0 ), _level( LL_DEBUG )
            {
            }

            /// destructor
            ~logger()
            {
            }

            /// set the output manager, you must call this function before you
            /// log anything.
            void set_output( output_type *ot )
            {
            assert( ot != 0 && "logger::set_output : invalid arguments." );
            _output = ot;
            }

            /// write log text
            void write_only( int level, const char *format, ... )
            {
            assert( _output != 0 && "logger::write_only : You must set up the output manager before you log anything." );
            static char buf[string_size];

            // checck the level
            if( level > _level ) return ;

            // format the string
            va_list list;
            va_start( list, format );
            vsprintf( buf, format, list );
            va_end( list );

            // output the log text
            _output->log( buf );
            }

            /// write log text and append prestring
            void write( int level, const char *format, ... )
            {
            assert( _output != 0 && "logger::write : You must set up the output manager before you log anything." );
            static char buf[string_size];

            // checck the level
            if( level > _level ) return ;

            // append pre-string
            std::size_t pos = _prestr( buf, level );

            // format the string
            va_list list;
            va_start( list, format );
            vsprintf( &buf[pos], format, list );
            va_end( list );

            // output the log text
            _output->log( buf );
            }

            /// set log level
            void set_level( int level )
            {
            assert( level > LL_MIN && level < LL_MAX && "logger::set_level : invalid arguments." );
            _level = level;
            }

            /// get the log level
            int get_level()
            {
            return _level;
            }

            private:
            /// output manager to collect log text.
            output_type *_output;
            /// pre-str to append some text before the log text
            prestr_type _prestr;
            /// log level
            int _level;
            };

            ///
            /// The file log output manager, write log text to the file.
            ///
            class file_output
            {
            public:
            /// constructor
            file_output()
            {
            }

            /// this constructor will open the file
            file_output( const std::string filename, std::ios_base::openmode _Mode = std::ios_base::out ) :
            _file_handle( filename.c_str(), _Mode )
            {
            }

            /// destructor
            ~file_output()
            {
            }

            /// open the file if it's not open
            bool open( const std::string filename, std::ios_base::openmode _Mode = std::ios_base::out )
            {
            if( _file_handle.is_open() )
            {
            return false;
            }

            _file_handle.open( filename.c_str(), _Mode );
            return _file_handle.is_open();
            }

            /// log
            void log( const char *str )
            {
            assert( _file_handle.is_open() && "file_output::log : you cannot write anything before you open the file!" );
            _file_handle << str ;
            _file_handle.flush();
            }

            private:
            /// output file
            std::ofstream _file_handle;
            };

            KL_COMMON_NAMESPACE_END

            #endif // end ___KL_LOGGER_H_
            貌似console下也可以調用GetAsyncKeyState
            re: 突破select的FD_SETSIZE限制 Kevin Lynx 2008-05-20 14:24
            @eXile
            謝謝提醒,win_fd_set_adapter.hpp確實是個方案。那估計是用__WSAFDIsSet也不是問題了。:)
            re: 突破select的FD_SETSIZE限制 Kevin Lynx 2008-05-20 13:03
            @2nd guest
            我覺得這個東西不復雜,只要保持模塊對外接口的簡潔,維護這么小的模塊不會那么復雜。
            re: 我開始感到厭倦了... Kevin Lynx 2008-05-20 11:32
            有同感,工作前很喜歡編程,身體越來越差,現在坐著就痛,編程的激情也被磨滅了。并且我薪水也低。所以很不爽。
            re: 腳本編程瑣話 Kevin Lynx 2008-05-16 17:46
            = = 都忘了你以前是怎樣的,貌似現在還可以
            @xbzg
            忽略即可,基本上你還需要忽略其他幾個默認鏈接的boost庫
            re: 彩虹島游戲登陸過程分析 Kevin Lynx 2008-05-14 14:43
            看能不能分析下網絡封包?
            re: 周記:找回激情 Kevin Lynx 2008-05-11 08:24
            還是給個評論:

            其實關于程序結構,其實就是我眼中的軟件架構,這種東西的經驗主要還是通過自己寫大程序總結獲得,配合設計模式軟件工程之類的理論,上升得會比較快,尤其是寫個庫出來,更會挑戰自己這方面的能力。簡單的功能封裝并不是一個庫該干的(這話熟悉吧?)當然看其他開源庫也會獲取相關經驗。對于boost我不敢說啥,很大很惶恐,只能單個小庫地仰慕一下。

            自我感覺現在有模板編程的思想,不過這東西,僅能用于基礎模塊的搭建。(我很滿意我的日志類,用Andrei書中的術語就是policy :D和我的multi_list :D---Bugs眼中的過度設計--確實有點過度)

            算法相關問題,我至今覺得那些書上的算法很少能帶給我們直接的實踐機會。可能你至今沒在工作中用到DP吧?不過我從不忽視算法的作用,在我眼中算法是讓人擁有堅實編程基礎的東西。所以有時候解決一個問題的時候,總有點捉襟見肘的感覺。不過想想,沒辦法啊,環境所致。哥們你就忍了吧。
            re: tcp要點學習-基礎概念 Kevin Lynx 2008-05-09 18:08
            @Xw.Y
            我的意思是硬件那一層(網絡協議棧)中的東西(鏈路層)
            @test
            感謝的經驗分享,現在選擇基本明了了,選lua也符合我自己的美學觀念。:D
            @Qestion
            Stackless Python is an enhanced version of the Python programming language. It allows programmers to reap the benefits of thread-based programming without the performance and complexity problems associated with conventional threads. The microthreads that Stackless adds to Python are a cheap and lightweight convenience which can if used properly, give the following benefits:
            Improved program structure.
            More readable code.
            Increased programmer productivity.

            似乎很有意思
            @劍孤寒
            貌似有個tolua++可以很輕松地解決這個問題。
            re: 讓我痛苦得涕淚橫流的Qt Kevin Lynx 2008-05-05 18:00
            據說qt4與qt3(以及之前的版本)有很大變化。
            我以前用QT基本上是在qt designer里做好了界面,然后再寫代碼,基本不用VS集成的那個。qmake其實挺好。
            @yafare
            例如?舉個例子代碼看看?(從對話框給的內容來看,似乎就是因為函數調用錯誤)
            re: 累到想吐 Kevin Lynx 2008-04-24 20:32
            我也累。。~_~##
            還在加班。。。
            @亨德列克
            不是那一行錯了,App和Game兩個類分屬不同模塊,為了不讓兩個模塊耦合,這里使用Listener *listener = (Listener*) p,而不是(App*)p。

            giscn和eXile (他刪除了他的第二條評論:) )的方法是正確的。可以被采用,再次表示感謝。

            這讓我意識到,void*在C++里缺乏安全性。
            共6頁: 1 2 3 4 5 6 
            99久久免费国产精品| 囯产精品久久久久久久久蜜桃| 久久超碰97人人做人人爱| 久久久久久久久无码精品亚洲日韩| 99国产精品久久久久久久成人热| 久久99国产精品二区不卡| 香港aa三级久久三级老师2021国产三级精品三级在 | 综合网日日天干夜夜久久 | 日韩亚洲欧美久久久www综合网| 久久国产精品视频| 无码日韩人妻精品久久蜜桃| 秋霞久久国产精品电影院| 久久青青色综合| 久久久无码精品午夜| 奇米综合四色77777久久| 久久久久亚洲av成人无码电影| 久久中文骚妇内射| 要久久爱在线免费观看| 久久99国产精品久久| 婷婷久久久亚洲欧洲日产国码AV | 蜜臀av性久久久久蜜臀aⅴ| 欧美久久久久久精选9999| 久久er99热精品一区二区| 国产精品久久婷婷六月丁香| 国产精品女同一区二区久久| 久久99精品久久久久久久久久| 久久人人爽人人爽人人片av麻烦| 欧美一区二区精品久久| 69SEX久久精品国产麻豆| 伊人久久综合精品无码AV专区| 久久影视国产亚洲| 日韩一区二区三区视频久久| 精品久久久无码中文字幕天天| 国产精品久久久久久久午夜片| 九九精品99久久久香蕉| 久久精品aⅴ无码中文字字幕重口| 中文国产成人精品久久不卡| 久久无码专区国产精品发布| 久久人妻AV中文字幕| 久久久久人妻一区精品色| 久久精品中文无码资源站|