• <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

            低調(diào)做技術(shù)__歡迎移步我的獨(dú)立博客 codemaro.com 微博 kevinlynx

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

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

            個(gè)人拙見。:)
            @francis
            thread2沒有獲得CPU權(quán)!thread2沒有被調(diào)度!
            這里的用法完全是條件變量的標(biāo)準(zhǔn)用法,如果你硬是要從理論上認(rèn)為它有問題,那你可以去查條件變量相關(guān)資料。這里的結(jié)構(gòu)和條件變量通用用法一樣。你甚至可以找本操作系統(tǒng)書,在上面找到條件變量的使用結(jié)構(gòu)。你想推翻這一切?建議你大量查閱條件變量相關(guān)資料。如果你還認(rèn)為有問題,你應(yīng)該去對(duì)發(fā)明條件變量的某個(gè)可能已經(jīng)死掉的牛人說(shuō):你這個(gè)條件變量的結(jié)構(gòu)有問題。
            @francis
            我讀了幾遍你的這次回復(fù),希望我沒有誤解你的意思:
            thread1被激活,取數(shù)據(jù),就可能導(dǎo)致container的size為0,一旦size為0,thread3繼續(xù)push的時(shí)候就可能會(huì)激活thread2。如果OS一直沒有調(diào)度到thread2,那么,container就可能經(jīng)歷過(guò)多次size為0,size不為0,也就是thread1和thread3發(fā)生多次數(shù)據(jù)交互。thread2看起來(lái)是慘了,因?yàn)閏ontainer曾經(jīng)有數(shù)據(jù),但是thread2卻沒取到?為什么呢?thread2根本沒被OS調(diào)度到,從沒有獲取到CPU控制權(quán),它又有什么理由不wait?

            歸根結(jié)底,你說(shuō)的這個(gè)問題,只是因?yàn)閠hread2沒有被調(diào)度到而已。
            @francis
            詳述下這種會(huì)出現(xiàn)問題的情況。如果可以模擬出現(xiàn)的話,麻煩基于multi_list這個(gè)類制造這種情況。
            @francis
            while( _container.size() == 0 ) _condition.wait();
            僅當(dāng)為空的情況下才wait的。代碼在邏輯上不存在大問題,因?yàn)檫@個(gè)基礎(chǔ)部件已經(jīng)被用于實(shí)際項(xiàng)目(用于保存驗(yàn)證服務(wù)器端的驗(yàn)證帳號(hào))。
            @francis
            我們看一次常規(guī)的同步操作:
            push_front()
            {
            guard<mutex_type> g(_mutex );
            ...
            }

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

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

            另一方面,如果每次push操作都進(jìn)行條件變量的signal,這個(gè)所謂的原語(yǔ)操作開銷有多大?
            查看condition::signal/wait代碼,其內(nèi)部還存在一個(gè)_wait_count的同步。另外,如果
            每次push都signal的話,那么pop操作也需要進(jìn)行wait,這樣以來(lái)它其實(shí)已經(jīng)不是條件變量,
            而是信號(hào)量了。

            我們所要的效果,就是在隊(duì)列元素為0時(shí),進(jìn)行pop操作的時(shí)候讓其阻塞而已。


            @francis
            關(guān)鍵在于,signal和wait會(huì)對(duì)外部mutex做操作。參見kl_condition.h相關(guān)代碼。
            @francis
            你可以查找‘條件變量’(condition variable)的相關(guān)資料。
            signal只在隊(duì)列尺寸為0時(shí)的push操作中調(diào)用,因?yàn)樵趐op中會(huì)在隊(duì)列尺寸為0時(shí)wait.
            @Strive
            很巧, 我恰好看過(guò)這個(gè)網(wǎng)站,感覺是個(gè)少年天才的主頁(yè)。之前搜索QQ協(xié)議,發(fā)現(xiàn)的。還下了他寫的QQ客戶端,不過(guò)有問題,我登陸Q后,就被T了。
            @zx
            高并發(fā)數(shù)不見得要使用async(不明白你所謂的Async模式是什么?我假設(shè)是異步IO),也不見得要使用Overlapped IO (我也不明白你說(shuō)的"IO的overlapped",我假設(shè)是windows下的Overlapped IO),一個(gè)event-driven的網(wǎng)路模型就很不錯(cuò)了。

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

            @true
            那就應(yīng)該沒問題了。‘應(yīng)用程序初始化失敗’,你用的是VS2005吧?那就跟BOOST沒關(guān)系了。新的問題跟項(xiàng)目設(shè)定有關(guān)系。具體搜索下網(wǎng)絡(luò)吧。:)
            我以前編譯ASIO例子程序的時(shí)候,就顯示地忽略了以下兩個(gè)庫(kù):
            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則沒遇到過(guò),你顯示地忽略掉看下如何?
            re: VS2005編譯libevent Kevin Lynx 2008-07-07 12:53
            libevent在windows下似乎沒多大實(shí)用價(jià)值(因?yàn)橛玫氖莝elect)。spserver的作者寫了個(gè)IOCP版本。
            貌似是有這樣的現(xiàn)象,例如libevent的VC6工程文件用RAR解開后就是壞的。
            ‘游戲之家站長(zhǎng)’的故事源遠(yuǎn)流長(zhǎng)。。。
            偶然發(fā)現(xiàn)LZ博客有我以前CSDN的鏈接,呵呵,現(xiàn)在我換到CPPBLOG來(lái)了,更新下鏈接吧。
            @飯中淹
            前面我說(shuō)了,condition和guard使用的是同一個(gè)mutex,在condition的wait里,會(huì)先_external_mutex.release();,然后push的時(shí)候,就不會(huì)阻塞在guard那里,于是condition.signal(元素為0時(shí),看下代碼),然后pop里的condition.wait就過(guò)了。
            @飯中淹
            不會(huì)的,condition和guard使用的都是同一個(gè)mutex。guard用于一般的同步,condition用于隊(duì)列元素為0時(shí)的臨界條件。
            @true
            事實(shí)上是我寫的. :D 我寫著玩,但是被用到我們的產(chǎn)品里。
            比較有意思的:

            /// 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
            貌似你誤解我意思了;)

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

            ’他更及時(shí),不用參與排隊(duì)‘:
            這個(gè)跟上面不是說(shuō)的同一個(gè)問題,隊(duì)列是用于實(shí)際業(yè)務(wù)處理,例如寫日志,上面那個(gè)說(shuō)的是線程。

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

            有點(diǎn)巧,我同事也犯過(guò)這個(gè)錯(cuò)。:D
            @關(guān)中刀客
            難道不開源?不知道能否分享下代碼。

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

            還有,一直想看下你的cobra是個(gè)什么東西
            @jigloo
            "網(wǎng)絡(luò)層用reactor模式封裝異步IO" 似乎proactor才是用于封裝異步IO的吧?

            關(guān)于你提出的這幾層封裝,不知道是否可以提供個(gè)簡(jiǎn)單的整體類圖?不甚感激。
            日志對(duì)于一個(gè)系統(tǒng)來(lái)說(shuō)確實(shí)是必不可少的基礎(chǔ)模塊。
            我用模板寫了個(gè)不依賴于具體‘寫’的日志類,簡(jiǎn)單的日志等級(jí)過(guò)濾。
            ///
            /// @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下也可以調(diào)用GetAsyncKeyState
            re: 突破select的FD_SETSIZE限制 Kevin Lynx 2008-05-20 14:24
            @eXile
            謝謝提醒,win_fd_set_adapter.hpp確實(shí)是個(gè)方案。那估計(jì)是用__WSAFDIsSet也不是問題了。:)
            re: 突破select的FD_SETSIZE限制 Kevin Lynx 2008-05-20 13:03
            @2nd guest
            我覺得這個(gè)東西不復(fù)雜,只要保持模塊對(duì)外接口的簡(jiǎn)潔,維護(hù)這么小的模塊不會(huì)那么復(fù)雜。
            re: 我開始感到厭倦了... Kevin Lynx 2008-05-20 11:32
            有同感,工作前很喜歡編程,身體越來(lái)越差,現(xiàn)在坐著就痛,編程的激情也被磨滅了。并且我薪水也低。所以很不爽。
            re: 腳本編程瑣話 Kevin Lynx 2008-05-16 17:46
            = = 都忘了你以前是怎樣的,貌似現(xiàn)在還可以
            @xbzg
            忽略即可,基本上你還需要忽略其他幾個(gè)默認(rèn)鏈接的boost庫(kù)
            看能不能分析下網(wǎng)絡(luò)封包?
            re: 周記:找回激情 Kevin Lynx 2008-05-11 08:24
            還是給個(gè)評(píng)論:

            其實(shí)關(guān)于程序結(jié)構(gòu),其實(shí)就是我眼中的軟件架構(gòu),這種東西的經(jīng)驗(yàn)主要還是通過(guò)自己寫大程序總結(jié)獲得,配合設(shè)計(jì)模式軟件工程之類的理論,上升得會(huì)比較快,尤其是寫個(gè)庫(kù)出來(lái),更會(huì)挑戰(zhàn)自己這方面的能力。簡(jiǎn)單的功能封裝并不是一個(gè)庫(kù)該干的(這話熟悉吧?)當(dāng)然看其他開源庫(kù)也會(huì)獲取相關(guān)經(jīng)驗(yàn)。對(duì)于boost我不敢說(shuō)啥,很大很惶恐,只能單個(gè)小庫(kù)地仰慕一下。

            自我感覺現(xiàn)在有模板編程的思想,不過(guò)這東西,僅能用于基礎(chǔ)模塊的搭建。(我很滿意我的日志類,用Andrei書中的術(shù)語(yǔ)就是policy :D和我的multi_list :D---Bugs眼中的過(guò)度設(shè)計(jì)--確實(shí)有點(diǎn)過(guò)度)

            算法相關(guān)問題,我至今覺得那些書上的算法很少能帶給我們直接的實(shí)踐機(jī)會(huì)。可能你至今沒在工作中用到DP吧?不過(guò)我從不忽視算法的作用,在我眼中算法是讓人擁有堅(jiān)實(shí)編程基礎(chǔ)的東西。所以有時(shí)候解決一個(gè)問題的時(shí)候,總有點(diǎn)捉襟見肘的感覺。不過(guò)想想,沒辦法啊,環(huán)境所致。哥們你就忍了吧。
            @Xw.Y
            我的意思是硬件那一層(網(wǎng)絡(luò)協(xié)議棧)中的東西(鏈路層)
            @test
            感謝的經(jīng)驗(yàn)分享,現(xiàn)在選擇基本明了了,選lua也符合我自己的美學(xué)觀念。: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.

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

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

            這讓我意識(shí)到,void*在C++里缺乏安全性。
            共6頁(yè): 1 2 3 4 5 6 
            久久久久久久综合日本亚洲| 亚洲av伊人久久综合密臀性色 | 九九久久精品国产| 久久久久黑人强伦姧人妻| 成人亚洲欧美久久久久| 久久亚洲精品视频| 国产午夜精品理论片久久| 久久se精品一区二区| 成人精品一区二区久久 | 国内精品人妻无码久久久影院| 精品无码久久久久久尤物| 久久99精品国产麻豆蜜芽| 欧美黑人又粗又大久久久| 99热热久久这里只有精品68| 国产精品中文久久久久久久| 94久久国产乱子伦精品免费| 精品国产乱码久久久久软件| 国产激情久久久久影院小草 | 精品久久亚洲中文无码| 91久久国产视频| 久久婷婷五月综合色奶水99啪| 精品久久久久久久久久久久久久久| 伊人久久综合无码成人网| 日本高清无卡码一区二区久久| 久久r热这里有精品视频| 久久久久高潮毛片免费全部播放 | 亚洲色婷婷综合久久| 亚洲午夜无码AV毛片久久| 欧美久久综合性欧美| 久久精品国产亚洲网站| 久久99国产综合精品| 久久棈精品久久久久久噜噜| 久久婷婷五月综合色奶水99啪| 久久久久久久综合综合狠狠| 精品免费久久久久国产一区| 久久成人影院精品777| 久久免费高清视频| 99久久精品久久久久久清纯| 欧美精品一区二区精品久久| 94久久国产乱子伦精品免费| 国产99久久久国产精品~~牛|