http://blog.csdn.net/zwleagle/article/details/8851400

http://blog.sina.com.cn/s/blog_a574f78401015v2o.html

http://www.dssz.com/1341360.html

http://www.dssz.com/1341355.html

多线程网络处理服务器demo

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <errno.h>
  4. #include <string.h>
  5. #include <sys/types.h>
  6. #include <netinet/in.h>
  7. #include <sys/socket.h>
  8. #include <sys/wait.h>
  9. #include <unistd.h>
  10. #include <arpa/inet.h>
  11. //#include <openssl/ssl.h>
  12. //#include <openssl/err.h>
  13. #include <fcntl.h>
  14. #include <sys/epoll.h>
  15. #include <sys/time.h>
  16. #include <sys/resource.h>
  17. #include <pthread.h>
  18. #include <assert.h>
  19. //#define DEBUG_TILERA
  20. #ifdef DEBUG_TILERA
  21. #include <tmc/alloc.h>
  22. #include <arch/cycle.h>
  23. #include <arch/spr.h>
  24. #include <tmc/cpus.h>
  25. #include <tmc/sync.h>
  26. #include <tmc/task.h>
  27. #endif
  28. /* These are non-NULL pointers that will result in page faults
  29. * under normal circumstances, used to verify that nobody uses
  30. * non-initialized list entries.
  31. */
  32. #define MAXBUF 1024
  33. #define MAXEPOLLSIZE 500000
  34. #define MAX_THREAD_NUMBER 200
  35. int  THREAD_NUMBER = 50;
  36. int kdpfd;
  37. struct epoll_event events[MAXEPOLLSIZE];
  38. struct epoll_event thread_events[MAX_THREAD_NUMBER][MAXEPOLLSIZE];
  39. int fdpool[MAX_THREAD_NUMBER] = {-1};
  40. pthread_t  handle_receive_thrdid[MAX_THREAD_NUMBER];
  41. int msgcount = 0;
  42. int timecount = 0;
  43. int count_packet= 0;
  44. pthread_mutex_t connet_count_lock = PTHREAD_MUTEX_INITIALIZER;
  45. int connect_count = 0;
  46. pthread_mutex_t curfds_lock;
  47. int curfds;
  48. char buffer[MAX_THREAD_NUMBER][MAXBUF + 1];
  49. pthread_t thread_count;
  50. cpu_set_t cpus;
  51. void BubbleSort(unsigned char R[],int n)
  52. {
  53. int i,j;
  54. unsigned char temp;
  55. for (i=0; i<n-1; i++ )
  56. {
  57. for (j=n-2; j>=i; j--)
  58. {
  59. if (R[j]>R[j+1])
  60. {
  61. temp=R[j];
  62. R[j]=R[j+1];
  63. R[j+1]=temp;
  64. }
  65. }
  66. }
  67. }
  68. /*
  69. setnonblocking - 设置句柄为非阻塞方式
  70. */
  71. int setnonblocking(int sockfd)
  72. {
  73. if (fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFD, 0)|O_NONBLOCK) == -1)
  74. {
  75. return -1;
  76. }
  77. return 0;
  78. }
  79. /*
  80. handle_message - 处理每个 socket 上的消息收发
  81. */
  82. static void *handle_count(void* arg)
  83. {
  84. int precount, speed;
  85. while(1)
  86. {
  87. precount = msgcount;
  88. sleep(5);
  89. timecount += 5;
  90. //printf("The tcp connection count is %d\n",count_tcp);
  91. //printf("The received packets count is %d, time %d\n",msgcount, timecount);
  92. speed = msgcount - precount ;
  93. printf("The received speed  is %d/5seconds, connect %d, tatol packets %d\n",speed, connect_count, msgcount);
  94. }
  95. return NULL;
  96. }
  97. static void * handl_receive_msg(void * arg)
  98. {
  99. int fdind = 0;
  100. int nfds = 0;
  101. int len;
  102. struct epoll_event ev;
  103. int fdi;
  104. char* buf ;
  105. fdind = (int)arg;
  106. buf = (char*)&buffer[fdind];
  107. // printf("fd... %d \n", fdind);
  108. while(1)
  109. {
  110. nfds = epoll_wait(fdpool[fdind], &thread_events[fdind][0], MAXEPOLLSIZE, -1);
  111. if (nfds == -1)
  112. {
  113. perror("epoll_wait");
  114. break;
  115. }
  116. for( fdi = 0; fdi < nfds; fdi++)
  117. {
  118. if((thread_events[fdind][fdi].events & EPOLLIN)
  119. /*&&(!(thread_events[fdind][fdi].events & EPOLLRDHUP))*/)
  120. {
  121. while((-1 != (len = recv(thread_events[fdind][fdi].data.fd, buf, MAXBUF, 0)))
  122. ||((-1 == len) && (EAGAIN != errno)))
  123. {
  124. //perror("recv error ");
  125. //printf("recv error %d  fd %d\n", errno, thread_events[fdind][fdi].data.fd);
  126. //goto next;
  127. if (len > 0)
  128. {
  129. /*printf
  130. ("%d receive message success   total %d bytes data  msgcount %d\n",
  131. new_fd,   len, msgcount);*/
  132. msgcount++;
  133. BubbleSort(buf ,len);
  134. }
  135. else if(len == 0)
  136. {
  137. //printf("the socket %d is closed \n", new_fd);
  138. epoll_ctl(fdpool[fdind], EPOLL_CTL_DEL, thread_events[fdind][fdi].data.fd,&ev);
  139. close(thread_events[fdind][fdi].data.fd);
  140. pthread_mutex_lock(&connet_count_lock);
  141. connect_count--;
  142. pthread_mutex_unlock (&connet_count_lock);
  143. break;
  144. }
  145. else
  146. {
  147. printf(" socket %d receive message fail error code: %d,  error message: '%s'\n",
  148. thread_events[fdind][fdi].events, errno, strerror(errno));
  149. epoll_ctl(fdpool[fdind], EPOLL_CTL_DEL, thread_events[fdind][fdi].data.fd,&ev);
  150. close(thread_events[fdind][fdi].data.fd);
  151. pthread_mutex_lock(&connet_count_lock);
  152. connect_count--;
  153. pthread_mutex_unlock (&connet_count_lock);
  154. //pthread_mutex_lock (&(curfds_lock));
  155. //curfds--;
  156. //pthread_mutex_unlock (&(curfds_lock));
  157. break;
  158. }
  159. }
  160. }
  161. /* else if((thread_events[fdind][fdi].events & EPOLLRDHUP))
  162. {
  163. epoll_ctl(fdpool[fdind], EPOLL_CTL_DEL, thread_events[fdind][fdi].data.fd,&ev);
  164. close(thread_events[fdind][fdi].data.fd);
  165. pthread_mutex_lock(&connet_count_lock);
  166. connect_count--;
  167. pthread_mutex_unlock (&connet_count_lock);
  168. printf("event.... %x \n", thread_events[fdind][fdi].events);
  169. }*/
  170. else
  171. {
  172. printf("other event %u\n",thread_events[fdind][fdi].events );
  173. }
  174. }
  175. }
  176. return NULL;
  177. }
  178. int fd_index = 0;
  179. int main(int argc, char **argv)
  180. {
  181. int listener, new_fd,  nfds, n, ret;
  182. socklen_t len;
  183. struct sockaddr_in my_addr, their_addr;
  184. unsigned int myport, lisnum;
  185. struct epoll_event ev;
  186. struct rlimit rt;
  187. int    fdind;
  188. int   ind ;
  189. if(5 != argc)
  190. {
  191. printf("Usage: %s <thread_number(0 ~ 200)> <port(0-65535)> <listen queue number>  <IP Address>   \n", argv[0]);
  192. exit(1);
  193. }
  194. if(argv[1])
  195. THREAD_NUMBER = atoi(argv[1]);
  196. if (argv[2])
  197. myport = atoi(argv[2]);
  198. else
  199. myport = 7838;
  200. if (argv[3])
  201. lisnum = atoi(argv[3]);
  202. else
  203. lisnum = 2;
  204. #ifdef DEBUG_TILERA
  205. if (tmc_cpus_get_my_affinity(&cpus) != 0)
  206. {
  207. printf("tmc_cpus_get_my_affinity() failed.\n");
  208. tmc_task_die("tmc_cpus_get_my_affinity() failed.");
  209. }
  210. if (tmc_cpus_count(&cpus) < MAX_THREAD)
  211. {
  212. printf("\nInsufficient cpus available.\n");
  213. tmc_task_die("Insufficient cpus available.");
  214. }
  215. #endif
  216. pthread_mutex_init (&connet_count_lock, NULL);
  217. pthread_mutex_init (&(curfds_lock), NULL);
  218. for( ind = 0; ind < THREAD_NUMBER; ind++ )
  219. {
  220. fdpool[ind] = epoll_create(MAXEPOLLSIZE);
  221. }
  222. for( ind = 0; ind < THREAD_NUMBER; ind++)
  223. {
  224. pthread_create(&handle_receive_thrdid[ind], NULL, &handl_receive_msg, (void*)ind);
  225. }
  226. if (pthread_create(&thread_count, NULL, &handle_count, NULL) != 0)
  227. {
  228. #ifdef DEBUG_TILERA
  229. tmc_task_die("pthread_create() failed.");
  230. #endif
  231. }
  232. /* 设置每个进程允许打开的最大文件数 */
  233. rt.rlim_max = rt.rlim_cur = MAXEPOLLSIZE;
  234. if (setrlimit(RLIMIT_NOFILE, &rt) == -1)
  235. {
  236. perror("setrlimit");
  237. exit(1);
  238. }
  239. else printf("set the system resource success!\n");
  240. /* 开启 socket 监听 */
  241. if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1)
  242. {
  243. perror("socket");
  244. exit(1);
  245. }
  246. else
  247. printf("socket create success!n");
  248. setnonblocking(listener);
  249. bzero(&my_addr, sizeof(my_addr));
  250. my_addr.sin_family = PF_INET;
  251. my_addr.sin_port = htons(myport);
  252. if (argv[4])
  253. my_addr.sin_addr.s_addr = inet_addr(argv[4]);
  254. else
  255. my_addr.sin_addr.s_addr = INADDR_ANY;
  256. if (bind
  257. (listener, (struct sockaddr *) &my_addr, sizeof(struct sockaddr))
  258. == -1)
  259. {
  260. perror("bind");
  261. exit(1);
  262. }
  263. else
  264. printf("IP address and port bing success!\n");
  265. if (listen(listener, lisnum) == -1)
  266. {
  267. perror("listen");
  268. exit(1);
  269. }
  270. else
  271. printf("start to work!\n");
  272. /* 创建 epoll 句柄,把监听 socket 加入到 epoll 集合里 */
  273. kdpfd = epoll_create(MAXEPOLLSIZE);
  274. len = sizeof(struct sockaddr_in);
  275. ev.events = EPOLLIN;
  276. ev.data.fd = listener;
  277. if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, listener, &ev) < 0)
  278. {
  279. fprintf(stderr, "epoll set insertion error: fd=%d\n", listener);
  280. return -1;
  281. }
  282. else
  283. printf("listen socket add to epoll success\n");
  284. curfds = 1;
  285. while (1)
  286. {
  287. /* 等待有事件发生 */
  288. nfds = epoll_wait(kdpfd, events, MAXEPOLLSIZE, -1);
  289. if (nfds == -1)
  290. {
  291. perror("epoll_wait");
  292. break;
  293. }
  294. /* 处理所有事件 */
  295. for (n = 0; n < nfds; ++n)
  296. {
  297. // printf("The number of fd %d \n", nfds);
  298. if (events[n].data.fd == listener)
  299. {
  300. new_fd = accept(listener, (struct sockaddr *) &their_addr,
  301. &len);
  302. if (new_fd < 0)
  303. {
  304. perror("accept");
  305. continue;
  306. }
  307. //else
  308. // printf("connect from  %x:%x, allocate socket for %x\n", inet_ntoa(their_addr.sin_addr), ntohs(their_addr.sin_port), new_fd);
  309. pthread_mutex_lock(&connet_count_lock);
  310. connect_count++;
  311. pthread_mutex_unlock (&connet_count_lock);
  312. setnonblocking(new_fd);
  313. ev.events = EPOLLIN | EPOLLET;
  314. ev.data.fd = new_fd;
  315. fdind = fd_index % THREAD_NUMBER;
  316. if (epoll_ctl(fdpool[fdind], EPOLL_CTL_ADD, new_fd, &ev) < 0)
  317. {
  318. fprintf(stderr, "add socket '%d' to epoll fail %s\n",
  319. new_fd, strerror(errno));
  320. // pool_destroy ();
  321. return -1;
  322. }
  323. fd_index++;
  324. //pthread_mutex_lock (&(curfds_lock));
  325. // curfds++;
  326. // pthread_mutex_unlock (&(curfds_lock));
  327. }
  328. else
  329. {
  330. printf("other event \n");
  331. }
  332. }
  333. }
  334. close(listener);
  335. // pool_destroy ();
  336. return 0;
  337. }

tilera试用

tilera处理器架构

前段时间同事搞来了一台使用tilera处理器的服务器,没错,就是那个由MIT专家做的、64个核的处理器,我非常好奇,所以也登上去体验体验。
tilera在硬件之上做了一个薄薄的软件层,叫hypervisior,再在这个hypervisior上装了一个linux,然后是gcc/g++/gdb等一套工具链。当然,这个linux是改过的,在内核arch/tile/目录里增加了东西,但是即使是增加了kernel代码,也只能跑在hypervisior上,不能直接跑在tilera硬件上。
我们用的是tilepro处理器,32位,64个核,每个核却只有863MHZ,所以多进程/多线程的程序有福了,我试了一下make -j60,感觉上确实比较快,但是,configure就慢得夸张。
在tilera上安装apache+php的过程中遇到几个小问题,主要是因为这个linux环境比较荒芜:
1. 从源码安装软件时,运行./configure遇到“configure: error: C compiler cannot create executables”,解决方法:
export CC=”gcc”
export CPP=”gcc -E”
2. ./configure还会遇到不能识别当前机器的处理器类型,解决方法:
./configure --build=i386
不用担心这个欺骗性的i386选项,对于可移植的c代码软件,这样不会造成什么问题。
我安装php最后还是失败了,所以拉倒,改装nginx做测试,起了20个nginx进程,通过千兆网卡做压力,却只能达到3000左右的QPS,这显然太低了。于是问了tilera的技术支持,他反馈说他们做过memcached的实验(据他说,facebook已经在用tilera机器专跑memcached),能到60万QPS,但是nginx多进程却很慢,他们也很疑惑,目前还在研究为什么。
看来tilera的软件层目前还偏薄弱,等一段时间吧,等linux-2.6.36稳定,且tilera的3.0版本的开发工具套件变为stable,我们再来关注关注。
====== 2011.01.06 ======
今天tilera公司的顾冉同学发来新消息,他们就用和我们一样的硬件环境(一片tilepro)和软件环境(MDE-2.1.0),10个左右的并发nginx,达到了将近2万QPS,比x86上的apache差一些,但是比我的测试结果已经好很多了。
也许是我的配置有问题,有待以后研究了。

Tilera多线程网络编程总结相关推荐

  1. day16多线程网络编程日志枚举

    多线程&网络编程 一.实现多线程 1.1 相关概念 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的一条执行路径.实际运作单位.简单理解:应用软件中互相独立,可以同时运 ...

  2. Linux多线程网络编程要义丨epoll与reactor原理

    linux多线程网络编程要义 1. epoll原理剖析 2. 单reactor原理以及应用 3. 多reactor原理以及应用 [Linux服务器系列]Linux多线程网络编程要义丨epoll与rea ...

  3. 【Linux服务器开发系列】详解多线程网络编程丨百分百干货分享丨学到就是赚到

    90分钟搞懂多线程网络编程模型 1. 网络编程关注的问题 2. 网络编程的几种模型reactor,one loop per thread及其变种 3. skynet,redis,nginx,memca ...

  4. HSHA多线程网络编程模型介绍

     我在上一篇的分享<Leader/Follower多线程网络模型介绍>中详细介绍了LF多线程网络模型的原理和代码分析.它的思路是减少线程上下文切换和数据拷贝时间,通过角色转换,来提高处 ...

  5. Java高并发与多线程网络编程

    目录 一. 基础 1. 线程介绍 2. 创建并启动线程 3. 函数式接口编程 4. Thread 构造器 5. 守护线程 线程关系 6. join 7. interrupt 8. 优雅的结束线程 9. ...

  6. python多线程网络编程_python网络编程之线程

    一 .背景知识 1.进程 之前我们已经了解了操作系统中进程的概念,程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,而这种执行的程序就称之为进程.程序和进程的区别就在于:程序是指令 ...

  7. python多线程网络编程_python之网络编程-多线程

    死锁现象,递归锁 所谓死锁:是指两个或两个以上的进程或线程在执行过程中,因为争夺资源而造成的一种互相等待的现象,若无外力作用,他们将无法推进下去,此时称系统处于死锁状态或系统产生了死锁,这些永远在相互 ...

  8. QT多线程网络编程程序崩溃问题与解决

    环境:Ubuntu14.04,Qt5.5 平台:QtCreator 场景:有以下三个线程:1.gstreamer循环取摄像头视频帧,25fps:2.HTTP循环请求消息并显示在QDoubleSpinB ...

  9. 多线程+SOCKET编程实现qq群聊的服务端和客户端

    多线程+SOCKET编程实现qq群聊的服务端和客户端 标签(空格分隔): 多线程 网络编程 线程同步 一.设计思路 1.服务端 每来一个客户端连接,服务端起一个线程维护: 将收到的消息转发给所有的客户 ...

  10. 索骥馆-编程语言之《网络编程实用教程(第2版)》扫描版[PDF]

    内容介绍: 本书主要介绍基于tcp/ip协议栈的套接字网络编程技术.全书分为10章,第1章介绍网络编程基础,第2章介绍套接字网络编程接口,第3章介绍windows环境的网络编程,第4章介绍mfc编程, ...

最新文章

  1. Solaris 10 系统维护
  2. 处理时间_7_60个Mysql日期时间函数汇总
  3. 大规模运行MongoDB应该知道的10件事
  4. Swift 学习手记1,pod 的 类库使用
  5. 密码学专题 密钥生成|分组加密的模式 ECB|CBC|CFB|OFB
  6. powerdesigner 16设计mysql数据库_PowerDesigner16 连接MySql 报错
  7. java自定义equals函数和hashCode函数
  8. “熊猫烧香”有新变种 可自动下载病毒
  9. 不知道如何raw转换成jpg格式?可以试试这几个软件
  10. 2016-2017 ACM-ICPC, NEERC, Southern Subregional Contest A Toda2 贪心
  11. no javac in (/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin)
  12. 金融网络安全和反欺诈方法论,金融新兴技术成熟度几何?
  13. 一个快速的人脸检测库
  14. 通用mapper 根据条件修改、查询
  15. java 垃圾收集器_JVM垃圾收集器详解
  16. vue指令学习——vue基本用法
  17. 趋势科技协助FBI破获大型跨国网络犯罪案 瓦解超过400万Botnet 殭尸大军
  18. 目标检测中的遮挡问题及优化
  19. mysql树状结构查询子节点和父节点
  20. 高中学历能找到程序员的工作吗?

热门文章

  1. Mac无法连接wifi和手机热点 解决方法
  2. Apache POI 读取、写入Excel文件教程
  3. 当生命科学遇上AI,会产生怎样1+1>2效果?
  4. 麻省理工学院(MIT)发明漏洞自动修复系统
  5. googlePlay订阅商品对接流程
  6. 《论文写作》——课程总结
  7. firewalld 规则配置
  8. android化学制图软件,虚拟化学实验室(Chemist)
  9. python脚本 游戏赚金币_一种王者荣耀刷金币方法(python脚本)
  10. js 解析lrc文件(歌词)