@田伯光
多個進程指向同一個文件的話,的確都可以寫進去。至于是不是穩定就不清楚了,呵呵,我一直是單進程多線程下使用,偶爾忘記程序已經啟動,第二次啟動,同樣會把log寫進文件。
你多測試下吧。
log4cplus的配置文件的配置方式網上不少,或者你留個郵箱,我發給你。
@mono,給你個可以編譯通過的宏,不知道你是win下還linux下,下面的宏都可以,另外流式的log不容易和printf、ace等對應,也看個人喜好,我是認為printf的方式更容易格式化輸出。
#define USE_LOG4CPLUS
#ifdef USE_LOG4CPLUS
#include <log4cplus/configurator.h>
#include <string>
static log4cplus::Logger logger= log4cplus::Logger::getInstance("Log");
static void init_log(const std::string & path)
{
log4cplus::PropertyConfigurator::doConfigure(path);
}
#define XLOG_ALL log4cplus::TRACE_LOG_LEVEL
#define XLOG_TRACE log4cplus::TRACE_LOG_LEVEL
#define XLOG_DEBUG log4cplus::DEBUG_LOG_LEVEL
#define XLOG_INFO log4cplus::INFO_LOG_LEVEL
#define XLOG_NOTICE log4cplus::INFO_LOG_LEVEL
#define XLOG_WARNING log4cplus::WARN_LOG_LEVEL
#define XLOG_ERROR log4cplus::ERROR_LOG_LEVEL
#define XLOG_CRITICAL log4cplus::FATAL_LOG_LEVEL
#ifdef WIN32
#if (_MSC_VER < 1500)
#define vsnprintf _vsnprintf
#endif
void inline win_log( int l, const char *format, ... )
{
if(logger.isEnabledFor(l)) {
schar buf[2046]={0};
va_list list;
va_start( list, format );
vsnprintf( buf, (size_t)2045,format, list );
va_end( list );
logger.forcedLog(l, buf, __FILE__, __LINE__);
}
}
#define X_LOG win_log
#else
#define X_LOG(l, ...) \
do { \
if(logger.isEnabledFor(l)) { \
char __buf__internal__[2046]={0}; \
snprintf(__buf__internal__,2045,__VA_ARGS__); \
logger.forcedLog(l, __buf__internal__, __FILE__, __LINE__); \
} \
} while(0)
#endif
@guosha
沒有用過。
log是個小功能,封裝下能做到透明使用基本就可以了。log4c依賴apr庫,如果你的主體程序不是在apr上構建的話,引入log4c不太舒服,呵呵。
。。。。。。。。。。。
路過。。。。。。。。。
。。。。。。。。。。。
@mono
#define USE_LOG4CPLUS
之后就編譯正確了吧,或者你把define USE_ACE_LOG那段去掉,可以用printf調式。
你的需求是什么樣子的?我用于server端程序,在main函數開始,來句:
#ifdef USE_LOG4CPLUS
init_log("./log.properties");
#endif
之后就再就是正常的程序啟動了,起各個協議棧、線程。當然log也都是打印在一個log文件里。
server端程序是一直運行的,不會退出,也就不存在消亡的問題。
re: 【原創】技術系列綜述(二) [未登錄] cppexplore 2008-11-10 09:36
@true
業務線程也不見得是多線程實現,尤其是是處理有上下文關聯關系(比如,rtsp協議,發了setup,才能發play,發送teardown之后才結束,不同階段狀態是不同的,http是無狀態的協議就另說了)邏輯的業務線程 ,一般都是單線程。把握住系統瓶頸的所在,在關鍵業務瓶頸處加多線程。另外,如果真想實現你說的情況,可以綁定connection和上層業務線程,我覺得這不會有性能的提升,當然也要看你的業務應用場景。
re: 網上大多數原理總結,UDP打洞原理[未登錄] cppexplore 2008-10-27 19:42
@伐木鼎鼎
呵呵,沒那么嚴重,可以做丟包重傳機制,這樣第一次a發給b的包可能會被拒收,第一個b發給a的也可能被拒收,但后面的包就正常了。
re: 【原創】技術系列之 線程(一) cppexplore 2008-10-23 15:39
@cui
呵呵,那是線程(二)中說的。
開始寫文章有不少錯誤的認識,后來對問題的看法再不停的調整,但舊有的文章中有的錯誤說法一直沒有更正。這篇文章里的信號量就是一例。
re: 【原創】技術系列綜述(一) cppexplore 2008-10-23 15:02
@powervv
不錯。二進制包更多的是對字節序、字節對齊問題的深入。關鍵的地方還是struct結構的準確定義,包括大小端、字節對齊問題。幸好一般協議在定義的時候,都會注意字節對齊問題,不夠1字節也會加padding補充,呵呵。
除了字節補充完成外,一般也都會保證4字節對齊完成,因此文中舉例的3字節結構體實際中是不存在的,即便是不要額外信息,協議也會在seq前規定1字節的padding補充滿4字節,在seq前補充也是為了避免設置pack(1)。
感謝補充!
re: 【原創】技術系列之 線程(二)[未登錄] cppexplore 2008-10-23 13:43
@cui
多謝。最近看到了,這個是信號安全的系統調用。
re: 【原創】技術系列綜述(一)[未登錄] cppexplore 2008-10-23 12:09
@小魚
忘記說et下的fd要設置非阻塞,其實多路復用函數下的fd一般都是非阻塞模式。雖然要減少read的次數,即便是lt模式下,也不能數據少就不讀,呵呵。ET下數據沒讀完,這個fd就永遠不會有事件上來了。et是邊緣觸發,就是從無數據到有數據這個變化點會觸發,lt是水平觸發,只要socket緩沖區有數據(當低潮屬性設置為1的時候,默認也是1)就會觸發。
re: 【原創】技術系列綜述(一)[未登錄] cppexplore 2008-10-23 12:02
ET模式下fd可讀 就要一直讀到返回-1并且errno是EAGAIN(信號中斷產生的EINTR要繼續)。可以man epoll看到。
...............
首頁上,你上篇文章之前的文章就是有關 成員函數委托 的,兩篇文章緊挨著
@創
listen后 accept前加fork是常見的設計,在不使用多路復用函數的情況下
@luke
區別就是fork前生成fd ,會導致多個進程在相同epoll上wait
想法不錯,把accept前的多進程用于多路復用函數,完美的方案,呵呵。
現實世界往往都不是那么完美。
還沒看到過select poll epoll類的應用前面可以加fork做這種領導者模型的。想想也不太現實,即使可以多進程select,那么一個被喚醒后,讀數據前,另一個也一定會被喚醒,這樣還是和單進程一樣。
re: 模版函數指針,C++委托的實現-原創[未登錄] cppexplore 2008-09-30 12:46
非常不錯!
強大的消息映射、狀態機事件映射都要靠這個才能完美的解決成員函數的問題。
re: 消息映射機制的簡單實現[未登錄] cppexplore 2008-09-30 12:32
頂一下
前幾天我也剛寫了一個,用在線程消息的處理中,我的消息類型做數組下標了,直接定位取處理函數,這都是無關緊要的細節。關鍵在ON_COMMAND宏的展現方式,我的處理線程消息,名字起做ON_MESSAGE
整體思路基本都是一樣的,呵呵。
re: 【原創】測試系列之 陪測程序示例[未登錄] cppexplore 2008-08-12 10:18
@flw
好東西 非常感謝
來拜拜牛人!
太牛了!!!!!!!!!!!!!!!
個人有的項目用異常,有的不用,感覺不用異常能對代碼的控制力更強,近來的項目已經不用異常了。感覺不到用異常的好處。
“當構造失敗時只有異常可以處理”,此處構造失敗是值什么?operator new失敗,還是構造函數失敗?一,std::nothrow_t類型的new,可以不拋異常,返回值為0表示,也可以看出標準制訂者也看不出有不使用異常的需要,二 構造函數中最好不要拋異常,構造函數出現異常,則不會調用析構函數,直接調用operator delete刪除內存,則構造函數本身要負責初始化一半的那些結構的清理工作,導致函數責任混亂,恰當的做法是為那些私有屬性初始化會發生失敗的操作單獨放在一個init()方法中。
re: 08年07月16日[未登錄] CppExplore 2008-07-17 20:05
@RichardHe
我猜也是你拿到返回的數據很困難,呵呵。
用socket吧 不需要用apache ace libevent那么復雜的封裝庫。寫個最基本最簡單的阻塞式socket,連接 發送 ,等響應,之后關閉就是了。發送就是發送這個好了:
POST /url HTTP/1.1\r\n
Content-Length: 24\r\n
Content-Type: application/txt\r\n
\r\n
username=jim&pass=mypass
詳細的信息可以問那邊要,他們一定有示例的頁面,用頁面發個請求,抓包就知道了。
re: 08年07月16日[未登錄] cppexplore 2008-07-17 17:20
@RichardHe
web也是用的socket。http的通訊方式如下:
建立連接(connect)
發送請求(send)
接收響應(recv)
斷開連接(close)
每次請求響應 都要建立連接,斷開連接,就是tcp短連接,也是http使用的方式。
http的格式可以看rfc,或者抓包看看就知道
一般是(post方式才需要body的):
post/get/header url http/1.1\r\n
header: value\r\n
Content-Length: ..\r\n
Content-Type: ..\r\n
\r\n
body
內嵌web可以說是個很快速的方案,只要你能拿到web上返回的數據,又何必自己寫socket發數據呢。或者可以一邊用內嵌web寫原型系統,一邊寫socket方式的。
re: 08年07月16日[未登錄] cppexplore 2008-07-17 13:01
@ 代李
可以
這對博主來說是個好方案,還是用socket發送,可以建立tcp短連接,發送的數據采用http協議格式的,這樣就兩邊皆大歡喜了吧。
re: 08年07月16日[未登錄] cppexplore 2008-07-17 12:18
根本原因還是因為那邊沒有socket,想直接用servlet吧。這樣他們那邊的改動很小,不需要涉入他們不熟悉的領域。被hook,指鍵盤輸入嗎,web下一樣可以。單純的得出結論:web輸入比client端輸入更安全,這個論調還需要詳細的論證吧,用客戶端的東東多了去了,也都沒用客戶端嵌入web的方式輸密碼。
https可以用ssl加密隧道,socket一樣可以。
這個問題就是要么你們改,他們不改,要么他們不改,你們用web輸入。
衡量2個方案的改動量,還是你們改比較簡單。
re: 08年07月16日[未登錄] cppexplore 2008-07-17 08:41
他們的server端是java之類的東西寫的吧。
他們不會或者懶得寫socket,想直接用servelet而已
re: 關于子進程和父進程--fork函數[未登錄] cppexplore 2008-07-08 11:47
系統全面的看下
要不 今天發現了fork 很驚奇感慨
明天又發現了pthread_cond,又很驚奇感慨
某天又發現了pthread_testcancel,又很驚奇感慨
某天天又發現了還有驚群的說法,再來感慨。
不如直接瀏覽下apue unp之類的書,全面的看下。
博主還是很有專研精神的,把握好大方向,基礎打堅實,.......
re: 關于子進程和父進程--fork函數 cppexplore 2008-07-07 12:53
唉 深入學習前 先多看看基礎的書
re: C++中如何獲得系統毫秒數 cppexplore 2008-07-06 20:39
linux上都是用gettimeofday
win上還是ftime,一般為了跨平臺,win上會實現gettimeofday,如下:
int inline gettimeofday (struct timeval *tp, void *tz)
{
struct _timeb timebuffer;
_ftime (&timebuffer);
tp->tv_sec = timebuffer.time;
tp->tv_usec = timebuffer.millitm * 1000;
return 0;
}
開源都是*inux友好的,tgz是linux下的常見壓縮包。tar zvxf .tgz解壓。
and removed!
re: Epoll筆記![未登錄] cppexplore 2008-06-24 11:32
沒覺得有什么必要性,每個socket都有自己的緩存的,不是共用的,再引入的復雜性和產出之間權衡下。網絡層上接線程消息隊列,屬于系統線程劃分的范疇,不僅epoll可以 select、poll等每個都可以。
完全與iocp相同,自己封裝就可,僅僅是外在的表現形式,并不是穿了一件AIO的外衣 就有AIO的性能。
re: C++隨筆分類列表(基礎)[未登錄] cppexplore 2008-06-24 09:19
@夢在天涯
哈哈,暴露了。我給他開玩笑呢。學生時代不好好學習,不思進取,不對,但也有很多變通的方法,明天下午遞交,前天晚上抱佛腳,這個錯誤太嚴重,更嚴重的是沒有找到變通的正確方法,老以為不通過任何的努力,天上就能掉餡餅,還能咬上一口。
re: Epoll筆記![未登錄] CppExplore 2008-06-23 12:25
socket本身有發送緩沖區的,不必再關聯寫數據隊列或緩存。不放心可以開大緩沖區。
@free2000fly
不好意思 原來是是連續的 呵呵
描述的太簡單太簡單了 看了之后難以跟進重現啊
放首頁,炫耀意義大于借鑒意義
re: 【原創】技術系列之 網絡模型(二)[未登錄] CppExplore 2008-06-19 13:26
@Jeff
udp也可以啊,模型簡單,在一個端口上復用就可以了,沒什么可寫的。
re: 服務器設計,開發的體會 cppexplore 2008-06-14 11:00
頂下!
re: SGI STL的內存池[未登錄] CppExplore 2008-06-12 22:52
唉 水已經滿了 會錯過很多東西的
re: std::queue的front的問題[未登錄] cppexplore 2008-06-10 12:39
value_type& front( );
只是說明返回的時候,不copy副本返回,直接返回私有屬性本身。
比如:
class A
{
public:
A():a_(9){}
const int & get_a()const{return a_;}
private:
int a_;
};
int main()
{
A a;
printf("it's %d\n",a.get_a()+4);
return 0;
}
a.get_a()+4這個其實就是a_+4,而不設計到內存copy問題。如果get_a()前沒有引用,則意味著先要把a_復制一副本,副本再和4相加。
該文中,int head=則是賦值操作,和后面的是否是引用無關,基本類型,當然會有效。
re: (C++)一個愚蠢的錯誤[未登錄] CppExplore 2008-06-06 22:00
暈倒
chinaunix上的是你哦,我是voipexplore。string內存布局不透明,只能用new類,不能用malloc類。
另樓上 包含string.h 是為了用memset
re: 寫了一個彈性物體碰撞模擬[未登錄] cppexplore 2008-06-06 12:05
呵呵 我要表達的主要意思在后半句。
re: 寫了一個彈性物體碰撞模擬[未登錄] cppexplore 2008-06-06 11:46
“等程序改好了之后再把代碼弄出來”??
呵呵 最好改好的時候把思路 主要難題 代碼放到首頁。本文這種放首頁就沒什么意義,授人以魚,不如授人以漁。
放在首頁的時候 能不能考慮下 文章是不是有一定的原創性 能不能讓看的人有點收獲
系統常用命令、vim常用命令都很有用處 為何不從深度、廣度兩方面著手整理下再發到首頁呢
re: 關于系統設計 cppexplore 2008-06-06 08:43
呵呵 博主很堅持啊
re: 【原創】系統設計之 必備外圍功能-log cppexplore 2008-06-05 19:44
呵呵 以為我的log框架你會喜歡,看來我錯了。不過還有一句話“如果你沒使用過log4cplus,ok,那么下載一個log4cplus,編譯,......,嘗試以下,你一定會驚嘆log4cplus的強大與美妙。”
還沒接觸過語音板卡 我們的應用沒有媒體編解碼或者dtmf檢測的。有時間向你討教討教,留個聯系方式吧,我的gtalk/gmail是gamil.com的,msn是live.com的,名稱都是zongjinliang。
@true
呵呵 linux上的應用服務器 軟交換服務器 流媒體服務器等。
re: 調查一下:你工作之余有沒有賺外快?[未登錄] cppexplore 2008-05-21 08:32
呵呵 兄弟拉到項目 找我合作啊 server端服務器協議開發 業務開發以及數據庫到web無所不能啊
re: 關于epoll[未登錄] cppexplore 2008-05-19 08:42
我測試的結果,兩者沒有明顯的性能差異。
re: 做個投票,大家支持[未登錄] cppexplore 2008-05-15 11:54
1、c 學生時代的唯一途徑,數據結構也是考研的必考科目:結構和算法
2、c 編譯原理的課程作業
3、a(學生時代),當時沒研究過stl,更沒聽過boost
4、b(現在),更多的是封裝實現模塊,極少考慮基礎的結構,純c下freebsd的宏結構也都很不錯。
linux/gcc/g++
re: FTP開發中下載文件的兩種方式[未登錄] cppexplore 2008-05-14 08:56
第一個信令端口超時了 一定間隔內發點命令過去就好
最后下載結束的時候 會檢測信令端口是否超時的