陈硕的Blog

共2页: 1 2 
@ian
把 CMakeLists.txt 中 -march=native 这句话去掉,重新编译试试。
@lys86_1205
你可以先单步跟踪一下。
@ 天道酬勤
你想说啥?
@天道酬勤
版本四,在你说的情况下,根本不会去 wait(),因为 while 条件不满足,因此不会丢信号。
@askforemore1018
在你说的这种情况下,版本八有可能丢,版本四不可能丢,想想为什么。
@其实俺不是什么所谓的坏人
我文中写了“现在用 NULL 也能达到 nullptr 的好处,大不了在某个头文件里define一下就行。”

不信在g++下试一下:

#include <stdio.h>

void foo(int)
{
printf("int");
}

void foo(char*)
{
printf("char*");
}

int main()
{
foo(NULL);
}

$ g++ null.cc
null.cc: In function 'int main()':
null.cc:15:11: error: call of overloaded 'foo(NULL)' is ambiguous
null.cc:15:11: note: candidates are:
null.cc:3:6: note: void foo(int)
null.cc:8:6: note: void foo(char*)
@zuhd
网上书店都是75折,不到70块,还免运费。
@xxf
2. 直接用string,如果data中含有二进制数据,如0,不是会丢失吗,而且如果这个段data很长,会发生一次数据拷贝吧?

有'\0'也不会丢失,你试试就知道。
如果跨线程发送消息,是会有一次拷贝,在C++11里可以用 move semantic 解决。
@唐诗
ConnectionEventHandler 和 DataEventHandler 二者的成员函数当然不一样,Connector 关心的是 writable event,Acceptor 关心的是 readable event。


说到底你说因为debug的原因而影响设计,但是 boost::bind 真的有那么难调试吗?
我故意制造一个core dump,调用栈一样容易看嘛。

一眼看出 muduo::net::Channel::handleEventWithGuard 调用了 cdns::Resolver::onRead,有困难吗?

(gdb) bt
#0 cdns::Resolver::onRead (this=0x7ffff7c7ee90, sockfd=6, t=...)
at /home/schen/muduo/examples/cdns/Resolver.cc:102
#1 0x000000000041011a in boost::function1<void, muduo::Timestamp>::operator() (this=0xc32ae0,
receiveTime=<value optimized out>) at /usr/include/boost/function/function_template.hpp:1013
#2 muduo::net::Channel::handleEventWithGuard (this=0xc32ae0, receiveTime=<value optimized out>)
at /home/schen/muduo/muduo/net/Channel.cc:90
#3 0x00000000004102fb in muduo::net::Channel::handleEvent (this=0xc32ae0,
receiveTime=<value optimized out>) at /home/schen/muduo/muduo/net/Channel.cc:65
#4 0x00000000004131b5 in muduo::net::EventLoop::loop (this=0x7ffff7c7ede0)
at /home/schen/muduo/muduo/net/EventLoop.cc:122
#5 0x000000000040d5c2 in main (argc=<value optimized out>, argv=0x7ffff7c7f0a8)
at /home/schen/muduo/examples/cdns/dns.cc:51
@杨军
> 不过(void)n;这种类似的语句也会带来额外的代码

Are you sure?
@杨军
你试试去掉它,然后用
BUILD_TYPE=release ./build.sh
编译。
@杨军
你认为 muduo 代码中的 UINTPTR_MAX 的作用是什么?
https://gist.github.com/3059083
@杨军
不改。你写个程序测一测吧。
@唐诗
改成 EventHandler 一样是错的,is-a 关系必须满足 Liskov 替换原则:
凡是程序里需要用到 EventHandler 的地方,换成它的任何一个派生类都是可行的。
但是显然 Acceptor、Connector 等等不具备这种可替换性。
@唐诗
除了我前面给的链接里那篇文章里给的原因,
更重要的理由就是:我认为这么建模是错的。
Acceptor is-not-a Channel, Acceptor uses a Channel to get readable event notification.
Connector is-not-a Channel, Connector uses a Channel to get writable event notification.
如此等等。

在muduo里,
EPollPoller is-a Poller,
PollPoller is-a Poller.
因此这里用了虚函数。其他地方 is-a 关系不成立。

继承不是为了复用,而是为了被复用。
@唐诗
你的意思是说:
Acceptor is-a Channel
Connector is-a Channel
EventLoop is-a Channel
TcpConnection is-a Channel
TimerQueue is-a Channel
像这样建模?
OO 中毒太深了吧?
@杨军
谢谢,会在下一版修正。
@唐诗
如果把Channel class设计成虚函数接口,那么在下面这五处用到Channel事件回调的地方,要么各自派生一个 inner DerivedChannel class,要么他们都直接继承Channel,两种做法问题都更大。
Acceptor::acceptChannel_
Connector::channel_
EventLoop::wakeupChannel_
TcpConnection::channel_
TimerQueue::timerfdChannel_

另见:muduo.chenshuo.com/2012/07/modern-c-api-in-muduo-part-1.html
@杨军
每次调用多了N+1次内存分配和释放的开销,好处是什么?节约了一个 tls 变量?
你要认为这是值得的,那就这样写呗。
@杨军
1. namelist 没有释放。
2. 每次调用都要分配释放内存,增加开销。
@杨军
写一个来看看?
@杨军
For thread safety.
@杨军
我测过,atexit() 处理500个Singleton没有问题。
sysconf(_SC_ATEXIT_MAX) 的返回值足够大。
@杨军
assert(namelist == NULL);
不需要释放。
@lijsf
UDP ?!
@ISO
佩服佩服!
@tfzxyinhao
有此计划。
@test
那你怎么关闭那个 pending connection ?
抑或根本不是 level-trigger reactor?
@test
这位名为“test”的网友,您测过吗?
@ouyang
按照你提供的数据,并发数 30000,每个连接存活时间 10 秒,可以计算出至少每秒钟要 accept 3000 个连接,并断开 3000 个旧连接(假设客户端主动断开连接,这样服务器不进入 time-wait 状态)。
对于服务端,每 accept 一个连接需要收两个 packet,发一个 packet。
每断开一个连接需要收两个 packet,发两个 packet。
这样一生一灭,操作系统每秒钟要处理 6~7 * 3000 = 18,000 ~ 21,000 个 packet。你确定你的服务器还有资源处理业务吗?
如果是单线程,平均每个连接的业务处理时间只有 0.3 毫秒,来得及完成任务吗?

对于 muduo,需要做的优化是修改 Acceptor::handleRead(),每次 accept N 个连接,而不是 1 个。N 的值可能是 10。
见下面这篇论文第 5.2 节: http://www.cs.uwaterloo.ca/~brecht/papers/ols-2004.pdf
@杨粼波
思考题:为什么 muduo::net::Buffer 不需要 reserve()?
@ouyang
> 限制最大并发连接数为多少合适呢?
看应用的复杂度,看多少个并发连接就把 CPU 或者 Memory 或者 IO 占满,然后设一个比它略小的上限,以保证服务质量。

> Muduo是否适合用来开发大并发(单机2万+)、短连接、小流量(整体网络流量不大)的TCP服务器?
应该可以,可能要为短连接适当优化一下 Acceptor。不过如果是短连接的话,单机并发 2万+ 是指什么?同时有 2 万个连接在线吗?那这不是长连接吗?
@路人甲
确实,output buffer 不必是连续的,反正复杂性丢给 TcpConnection 呗,可以用 writev 来减少系统调用次数。
@杨粼波
“调用reserve()才会预分配内存”?!这是哪家的 STL?
我原文说了,“vector 的 capacity() 以指数方式增长,让 push_back() 的平均复杂度是常数。”
如果“调用reserve()才会预分配内存”如何达到 push_back 的平均复杂度要求?

几行代码就能验证的事情:

vector<char> vec;
printf("%zd %zd\n", vec.size(), vec.capacity());
vec.resize(1024);
printf("%zd %zd\n", vec.size(), vec.capacity());
vec.resize(1300);
printf("%zd %zd\n", vec.size(), vec.capacity());

运行结果:

0 0
1024 1024
1300 2048


原话奉还:“自己先好好学一学STL。这些都是STL的内存分配机制的问题。
自己先多学点东西吧。”
@regexp
局域网内 NTP 校准的准确度是多少微秒?
局域网内的 latency 是多少微秒?
这样直接测试的结果有意义吗?
@zuhd
Live Writer 和 gpic。
画图一天,码字一天。
@陈梓瀚(vczh)
1. 我的这两篇文章跟“编译器版本”或“编译器升级”有任何关系吗?所有库和可执行文件都应该用相同的编译器版本来 build,不影响文章的观点。
2. 这两篇文章主要是从库的作者的角度来谈,库的作者和应用程序的作者是两个人群。如果要求每个应用程序都自己编译所用的动态库,那么这属于我说的“源代码发布”,和静态发布是一样的,也不用怎么考虑二进制兼容性,只要应用程序做好 full build 就行。
3. extern "C" 跟本文有什么关系?动态库必须以 extern "C" 来提供接口?
@yrj
请先定义“本质”,explicit 与 implicit 算不算本质?
@violet
你的意思是
string name;
string address;

string name, address;
要难看?
@vczh
不是偷不偷懒的问题。假设你是一个 shared library 的维护者,你的 library 被另外两三个团队使用了。你发现了一个安全漏洞,或者某个会导致 crash 的 bug 需要修复,那么你修复之后,能不能直接部署 library 的二进制文件?有没有破坏二进制兼容性?会不会破坏别人团队已经编译好的投入使用的可执行文件?是不是要强迫别的团队重新编译链接,把可执行文件也发布新版本?会不会打乱别人的 release cycle?这些都是工程开发中应该考虑的问题。
@classyk
这个好吧,用缩进。注释函数的时候把 // 放第一列,注释 for 循环的时候把 // 与 for 上面一行语句对齐。
@boquan
是在自己的测试程序中实现相应的统计功能.
@imjj
希望看到 client 端的 ACE 实现。
@ppx
Excel 2007 家庭版
@cpp
vector 能伸缩呗,适合不定长的消息。
@chaogu
这是典型的 busy-waiting,建议改为:

19 pthread_mutex_lock(&mutex);
20 shareQuueue.push(shareObject);
++ pthread_cond_signal(&condvar);
21 pthread_mutex_unlock(&mutex);

30 pthread_mutex_lock(&mutex);
31 while (shareQueue.size() < 1){
++ pthread_cond_wait(&condvar, &mutex);
34 }
35 shareObject = shareQueue.pop();
36 pthread_mutex_unlock(&mutex);

参考:
http://github.com/chenshuo/recipes/blob/master/thread/BlockingQueue.h
@chaogu
循环体内有没有 pthread_cond_wait ? 或者贴一下代码骨架吧。
@chaogu
Linux 上用什么方式等待?
共2页: 1 2 
<2011年6月>
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789

导航

统计

常用链接

随笔分类

随笔档案

相册

搜索

最新评论

阅读排行榜

评论排行榜