Chinaunix首页 | 论坛 | 博客
  • 博客访问: 96968
  • 博文数量: 31
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 380
  • 用 户 组: 普通用户
  • 注册时间: 2014-02-24 22:04
文章分类

全部博文(31)

文章存档

2014年(31)

我的朋友

分类: C/C++

2014-10-17 11:53:05


main
    |-----......
    |-----socketServer
    |-----tcpsetserveropt
    |-----daemon_init
    |-----tracker_service_init
    |-----.....



点击(此处)折叠或打开

  1. g_thread_data = (struct tracker_thread_data *)malloc(sizeof( \
  2.                 struct tracker_thread_data) * g_work_threads)
为全局g_thread_data分配空间,g_thread_data指向的也是一段连续内存,连续内存按照tracker_thread_data对象的个数进行划分


点击(此处)折叠或打开

  1. g_tracker_thread_count = 0;
  2.     pDataEnd = g_thread_data + g_work_threads;
  3.     for (pThreadData=g_thread_data; pThreadData<pDataEnd; pThreadData++)
  4.     {
  5.         pThreadData->ev_base = event_base_new();//创建eventbase
  6.         if (pThreadData->ev_base == NULL)
  7.         {
  8.             result = errno != 0 ? errno : ENOMEM;
  9.             logError("file: "__FILE__", line: %d, " \
  10.                 "event_base_new fail.", __LINE__);
  11.             return result;
  12.         }

  13.         if (pipe(pThreadData->pipe_fds) != 0)//创建管道
  14.         {
  15.             result = errno != 0 ? errno : EPERM;
  16.             logError("file: "__FILE__", line: %d, " \
  17.                 "call pipe fail, " \
  18.                 "errno: %d, error info: %s", \
  19.                 __LINE__, result, STRERROR(result));
  20.             break;
  21.         }

  22.         if ((result=set_nonblock(pThreadData->pipe_fds[0])) != 0)//设置非阻塞
  23.         {
  24.             break;
  25.         }

  26.         if ((result=pthread_create(&tid, &thread_attr, \//创建工作线程
  27.             work_thread_entrance, pThreadData)) != 0)
  28.         {
  29.             logError("file: "__FILE__", line: %d, " \
  30.                 "create thread failed, startup threads: %d, " \
  31.                 "errno: %d, error info: %s", \
  32.                 __LINE__, g_tracker_thread_count, \
  33.                 result, STRERROR(result));
  34.             break;
  35.         }
  36.         else //创建线程成功
  37.         {
  38.             if ((result=pthread_mutex_lock(&tracker_thread_lock)) != 0)//加锁
  39.             {
  40.                 logError("file: "__FILE__", line: %d, " \
  41.                     "call pthread_mutex_lock fail, " \
  42.                     "errno: %d, error info: %s", \
  43.                     __LINE__, result, STRERROR(result));
  44.             }
  45.             g_tracker_thread_count++; //修改全局线程数目,这里加锁是为了防止该变量在其他线程中被修改
  46.             if ((result=pthread_mutex_unlock(&tracker_thread_lock)) != 0)
  47.             {
  48.                 logError("file: "__FILE__", line: %d, " \
  49.                     "call pthread_mutex_lock fail, " \
  50.                     "errno: %d, error info: %s", \
  51.                     __LINE__, result, STRERROR(result));
  52.             }
  53.         }
  54.     }
该段代码在tracke_service_init函数中初始化了全局g_thread_data对象,包括为每个tracker_thread_data对象中的eventbase初始化,为每个tracker_thread_data对象中的pipe初始化为每个tracker_thread_data对象创建一个工作线程,修改全局g_tracker_thread_count工作线程记录数变量

下面介绍work_thread_entrance函数,该函数是工作线程的入口函数

点击(此处)折叠或打开

  1. static void *work_thread_entrance(void* arg)
  2. {
  3.     int result;
  4.     struct tracker_thread_data *pThreadData;
  5.     struct event ev_notify;//创建一个event

  6.     pThreadData = (struct tracker_thread_data *)arg;
  7.     do
  8.     {
  9.         event_set(&ev_notify, pThreadData->pipe_fds[0], \ //设定event监听管道pipe_fds[0]
  10.             EV_READ | EV_PERSIST, recv_notify_read, NULL);
  11.         if ((result=event_base_set(pThreadData->ev_base, &ev_notify)) != 0)//邦定event到event_base
  12.         {
  13.             logCrit("file: "__FILE__", line: %d, " \
  14.                 "event_base_set fail.", __LINE__);
  15.             break;
  16.         }
  17.         if ((result=event_add(&ev_notify, NULL)) != 0)
  18.         {
  19.             logCrit("file: "__FILE__", line: %d, " \
  20.                 "event_add fail.", __LINE__);
  21.             break;
  22.         }

  23.         while (g_continue_flag)
  24.         {
  25.             event_base_loop(pThreadData->ev_base, 0);
  26.         }
  27.     } while (0);

  28.     event_base_free(pThreadData->ev_base);

  29.     if ((result=pthread_mutex_lock(&tracker_thread_lock)) != 0)
  30.     {
  31.         logError("file: "__FILE__", line: %d, " \
  32.             "call pthread_mutex_lock fail, " \
  33.             "errno: %d, error info: %s", \
  34.             __LINE__, result, STRERROR(result));
  35.     }
  36.     g_tracker_thread_count--;
  37.     if ((result=pthread_mutex_unlock(&tracker_thread_lock)) != 0)
  38.     {
  39.         logError("file: "__FILE__", line: %d, " \
  40.             "call pthread_mutex_lock fail, " \
  41.             "errno: %d, error info: %s", \
  42.             __LINE__, result, STRERROR(result));
  43.     }

  44.     return NULL;
  45. }


在该函数中,要完成以下工作
(1) 执行event_set关联event到pipe_fds[0],监听EV_READ与EV_PERSIST事件
(2) 执行event_add,把event绑定到eventbase上
(3) 执行event_add函数
(4) 执行event_base_loop函数,开始event循环

这样,线程开始监听pipe_fds[0]上的EV_READ与EV_PERSIST事件,当事件被触发后,调用事件处理函数recv_notify_read,该函数将在下一节进行分析



阅读(1351) | 评论(0) | 转发(0) |
0

上一篇:第九步:tracker_service_init函数分析(part 1)

下一篇:没有了

给主人留下些什么吧!~~