lisk之初发布

企鹅
博客专家认证
业界专家认证
2013-04-23 12:56:03
加精
my blog: http://blog.csdn.net/menggucaoyuan/article/details/8837508
...全文
10414 52 打赏 收藏 转发到动态 举报
写回复
用AI写文章
52 条回复
切换为时间正序
请发表友善的回复…
发表回复
Metz 2015-03-31
  • 打赏
  • 举报
回复
企鹅 2013-05-20
  • 打赏
  • 举报
回复
lisk0.2.3发布了,blog是 http://write.blog.csdn.net/postedit/8952357。 今天抽时间写blog介绍了lisk的网络接口,blog是http://blog.csdn.net/menggucaoyuan/article/details/8952357 。
Mymakekuhu 2013-05-17
  • 打赏
  • 举报
回复
顶个先!
企鹅 2013-05-09
  • 打赏
  • 举报
回复
上面笔误,在liskv0.2.3中可见到更改后的代码。 实际上,发生EINTR错误时候,可以通过select或者poll或者epoll函数通过判断是否可写来判断connect是否已经成功。但为了节省处理,lisk直接认为这种情况为连接成功,因为连接失败的几率极小。
企鹅 2013-05-09
  • 打赏
  • 举报
回复
又看了一遍UNP vol1 ver3,在page 115发现这样一段话:“这段代码所做的事情自己重启被中断的系统调用。对于accept以及诸如read、write、select和open之类的函数来说,这是合适的。不过有一个函数我们不能重启:connect。如果该函数返回EINTR,我们就不能再次调用它,否则将立即返回一个错误。” lisk中对connect返回-1且errno为EINTR时候,connect_server函数返回-3,即要求客户端尝试再次重连,根据上面这句话可知这里判断错误。 lisk中有函数sys_signal,这个封装的sigaction的sa_flags为SA_RESTART,即中断处理完毕后重新调用被中断的系统调用。 为了节省处理,lisk直接认为这种情况为连接成功。修改后的connect_server函数为: n4 connect_server(n4 sock, net_addr_p svr_addr) { n4 ret; n4 flag; SAEX sa; if (IS_LT(sock, 0) || IS_NL(svr_addr)) { RET_INT(-1, "@sock = %d, @svr_addr = %p", sock, svr_addr); } na_2_sa(svr_addr, &sa); //flag == 0, success; flag == -1, fail; flag == 1, retry flag = 0; ret = connect(sock, (SA_P)(&sa), sizeof(sa)); if (IS_MN(ret)) { switch (errno) { case EINPROGRESS: case EINTR: // can not restart connect, page 115 of unp vol 3 version 3 case EISCONN: { flag = 0; } break; case EAGAIN: { flag = 1; } break; case EALREADY: case ECONNRESET: case EHOSTUNREACH: case ENETUNREACH: case ETIMEDOUT: { flag = -1; } break; default: { flag = -1; } break; } } //failure if (IS_EQ(flag, -1)) { OUTPUT_ERROR("connect(sock = %d) = %d", sock, ret); RET_INT(-2, "connect(sock = %d, &addr {ip = %s, port = %u} = %p, addr len = %zu) = %d", sock, svr_addr->ip, svr_addr->port, &sa, sizeof(sa), ret); } //retry if (IS_EQ(flag, 1)) { OUTPUT_ERROR("connect(sock = %d) = %d", sock, ret); RET_INT(-2, "connect(sock = %d, &addr {ip = %s, port = %u} = %p, addr len = %zu) = %d", sock, svr_addr->ip, svr_addr->port, &sa, sizeof(sa), ret); } RET_INT(0, nil_str); } 另外lisk的file_read、file_read以及sock_drive_handle_accept中对EINTR错误的处理都有break改成continue。 在liskv0.2.4中可见到更改后的代码。
hugett 2013-05-05
  • 打赏
  • 举报
回复
支持一下~~
xiaoji0507 2013-05-04
  • 打赏
  • 举报
回复
继续断楼。方便楼主回复。Linux版木有人气呀。。。
企鹅 2013-05-03
  • 打赏
  • 举报
回复
lisk中的lisk_type.h定义了若干数据类型: #define n1 char #define n2 short int #define n4 int #define n8 long long int #define nw long int #define u1 unsigned char #define u2 unsigned short int #define u4 unsigned int #define u8 unsigned long long int #define uw unsigned long int #define f4 float #define f8 double #define fw long double #define vd void #define vd_p void* #define vd_pp void** 上面的类型定义规律如下: 1 n开头代表整形 因为int行变量的匈牙利命名法前缀就是n,据说来自于basic的num或number常用整型变量名称 2 u开头代表unsigned 3 f开头代表float 4 以数字结尾代表变量的内存占用byte数目,w(意思是word)代表不固定内存大小的类型。 如nw是long int,在32位os上其是4字节大小,在64位机上是8字节大小;而fw则是long double,fw在linux上是12个字节,windows上是16个字节。 至于为什么用define而不是typedef关键字来定义不同类型,是因为我有以下工作经历。最简单的,写跨32位与64位的linux程序时候,用头文件stdint.h中的类型定义即可,但是使用printf或者snprintf函数的时候,gcc会给出很多warning甚至是error,所以我就重新定义了数据类型,并使用define关键字来避免这个错误警告。 第二个原因就是,C语言函数的所有变量一般都要在函数开始部分声明,而短小精悍的类型声明可以很容易使得这部分代码整洁划一。 lisk的网络框架lisk_network是一个基于回调函数的异步网络框架。由于lisk是单线程的,所以也可以说它是半异步的网络框架。
xiaoji0507 2013-05-03
  • 打赏
  • 举报
回复
企鹅 2013-05-03
  • 打赏
  • 举报
回复
lisk 0.2.2版发布了,url:http://download.csdn.net/detail/menggucaoyuan/5326200 与以往一样,仍然是零分下载。 本次lisk中添加了tcp客户端接口,其实只添加了一个对外接口以保持网络框架接口的简洁性。单进程下的lisk算是完美了。以后工作中如果用到多线程,并且本人多线程使用经验丰富之后,再考虑lisk多线程版本的开发,省得误人子弟。 五一之前曾考虑开发windows版本,现在恐怕要跳票了。因为如果要开发win版,第一网络部分我就得学习windows的iocp,而目前暂无兴趣学习使用它,第二其他的内存操作部分并无linux与windows的区别,而且vs2012现在我看也可以完美支持gcc的部分特性,基于上面两条原因我就不开发win版本的lisk了。 使用lisk下的网络测试用例network_client_test与network_server_test的时候,请注意修改lisk/exam/lisk.conf文件中的IP地址。 另外,运行那两个测试用例的时候,程序可能有以下错误提示: 2013-05-03_01-57-19_1367560639, lisk/src/lisk_network.c-set_max_sock_num-1165, [ERROR]: setrlimit(RLIMIT_NOFILE, &limit = 0x7fffbf23ac80) = -1, Err code 1, Operation not permitted 2013-05-03_01-57-19_1367560639, lisk/src/lisk_network.c-set_max_sock_num-1166, [ERROR]: ret = -1, setrlimit(RLIMIT_NOFILE) = -1 这是由于文件lisk/src/lisk_network.c使用了setrlimit函数,用户身份须为root。 所以这个问题有两个解决办法:第一,用sudo获取root权限,然后运行测试用例;第二,让他继续跑下去好了,如果仅仅是为了测试框架的可用性,这个错误不会影响测试结果的正确性。
xiaoji0507 2013-05-03
  • 打赏
  • 举报
回复
断楼
xiaoji0507 2013-05-03
  • 打赏
  • 举报
回复
企鹅 2013-05-02
  • 打赏
  • 举报
回复
介绍lisk中log的blog http://blog.csdn.net/menggucaoyuan/article/details/8868026
企鹅 2013-05-02
  • 打赏
  • 举报
回复
介绍多级hash的blog http://blog.csdn.net/menggucaoyuan/article/details/8856589
企鹅 2013-05-02
  • 打赏
  • 举报
回复
lisk包含了一个网络框架以及众多方便内存操作的数据结构。
善良超锅锅 2013-04-30
  • 打赏
  • 举报
回复
lisk 是什么?
kangyan392595157 2013-04-28
  • 打赏
  • 举报
回复
感谢分享。!
dfasri 2013-04-27
  • 打赏
  • 举报
回复
我想问问里面的atom的操作, 是用什么汇编来写的..没见过的汇编代码
企鹅 2013-04-26
  • 打赏
  • 举报
回复
在我的我的sock_drive_send,当用户调用的时候,这个函数直接上来就写了,没有判断是否EPOLLOUT,如果写不完,再注册EPOLLOUT事件一旦写完,写缓冲没有数据,要立即把EPOLLOUT关闭。因为os的写缓冲一般都有空的,如果你注册了epollout,os会不断通知你,而你的写buf为空,这是浪费系统资源的行为。 一个同事考虑到LT的epoll一次把缓冲区读完,才使得epoll在et和lt两种模式下没啥区别。 epoll收到EPOLLIN事件的时候,lisk用recvmsg外加一个64k的缓冲区读数据。同事建议在recvmsg外加一个循环,以把数据读完。我觉得如果没有修改os的recvbuf, 用64k的buf已经够了。recvmsg和recv都是原子读,如果os的recvbuf不大于64k,你用一个64k的char 数组就够了。循环的第二次不可能读到数据。 欢迎各位回帖,交流看法。
企鹅 2013-04-26
  • 打赏
  • 举报
回复
错了,是介绍lisk的lisk_mul_hash模块的blog。夜深早休息,脑子容易犯浑啊.^_^
加载更多回复(29)

18,772

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 专题技术讨论区
社区管理员
  • 专题技术讨论区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧