3. I/O Handler的管理

3.1. IO句柄与Select_Reactor的分发集成

3.1.1. dispatch_io_handlers 函数

ace/Select_Reactor_T.cpp dispatch_io_handlers 函数

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
template <class ACE_SELECT_REACTOR_TOKEN> int
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::dispatch_io_handlers
(ACE_Select_Reactor_Handle_Set &dispatch_set,
int &number_of_active_handles,
int &number_of_handlers_dispatched)
{
ACE_TRACE ("ACE_Select_Reactor_T::dispatch_io_handlers"); // Handle output events (this code needs to come first to handle the
// obscure case of piggy-backed data coming along with the final
// handshake message of a nonblocking connection). if (this->dispatch_io_set (number_of_active_handles,
number_of_handlers_dispatched,
ACE_Event_Handler::WRITE_MASK,
dispatch_set.wr_mask_,
this->ready_set_.wr_mask_,
&ACE_Event_Handler::handle_output) == -1)
{
number_of_active_handles -= number_of_handlers_dispatched;
return -1;
} // ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE_Select_Reactor_T::dispatch - EXCEPT\n")));
if (this->dispatch_io_set (number_of_active_handles,
number_of_handlers_dispatched,
ACE_Event_Handler::EXCEPT_MASK,
dispatch_set.ex_mask_,
this->ready_set_.ex_mask_,
&ACE_Event_Handler::handle_exception) == -1)
{
number_of_active_handles -= number_of_handlers_dispatched;
return -1;
} // ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE_Select_Reactor_T::dispatch - READ\n")));
if (this->dispatch_io_set (number_of_active_handles,
number_of_handlers_dispatched,
ACE_Event_Handler::READ_MASK,
dispatch_set.rd_mask_,
this->ready_set_.rd_mask_,
&ACE_Event_Handler::handle_input) == -1)
{
number_of_active_handles -= number_of_handlers_dispatched;
return -1;
} number_of_active_handles -= number_of_handlers_dispatched;
return 0;
}

3.1.2. dispatch_io_set 函数

ace/Select_Reactor_T.cpp dispatch_io_set 函数

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
template <class ACE_SELECT_REACTOR_TOKEN> int
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::dispatch_io_set
(int number_of_active_handles,
int &number_of_handlers_dispatched,
int mask,
ACE_Handle_Set &dispatch_mask,
ACE_Handle_Set &ready_mask,
ACE_EH_PTMF callback)
{
ACE_TRACE ("ACE_Select_Reactor_T::dispatch_io_set");
ACE_HANDLE handle; ACE_Handle_Set_Iterator handle_iter (dispatch_mask); while ((handle = handle_iter ()) != ACE_INVALID_HANDLE &&
number_of_handlers_dispatched < number_of_active_handles)
{
++number_of_handlers_dispatched;
this->notify_handle (handle,
mask,
ready_mask,
this->handler_rep_.find (handle),
callback); // clear the bit from that dispatch mask,
// so when we need to restart the iteration (rebuilding the iterator...)
// we will not dispatch the already dispatched handlers
this->clear_dispatch_mask (handle, mask); if (this->state_changed_)
{ handle_iter.reset_state ();
this->state_changed_ = false;
}
} return 0;
}

3.1.3. notify_handle 函数

ace/Select_Reactor_T.cpp notify_handle 函数

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
template <class ACE_SELECT_REACTOR_TOKEN> void
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::notify_handle
(ACE_HANDLE handle,
ACE_Reactor_Mask mask,
ACE_Handle_Set &ready_mask,
ACE_Event_Handler *event_handler,
ACE_EH_PTMF ptmf)
{
ACE_TRACE ("ACE_Select_Reactor_T::notify_handle");
// Check for removed handlers.
if (event_handler == 0)
return; bool const reference_counting_required =
event_handler->reference_counting_policy ().value () ==
ACE_Event_Handler::Reference_Counting_Policy::ENABLED; // Call add_reference() if needed.
if (reference_counting_required)
{
event_handler->add_reference ();
} int const status = (event_handler->*ptmf) (handle);
if (status < 0)
this->remove_handler_i (handle, mask);
else if (status > 0)
ready_mask.set_bit (handle); // Call remove_reference() if needed.
if (reference_counting_required)
event_handler->remove_reference ();
}

如果回调函数 status < 0, 则调用移除该 handle 的对应 mask:this->remove_handler_i (handle, mask) 。

如果回调函数 status > 0, 这表明该 handle 需要继续被调度处理,则需要将该 handle 设置到 ready_set_ 中再次被派发。

3.2. handler注册

3.2.1. register_handler 函数流程

ace/Select_Reactor_T.cpp register_handler 函数

 1
2
3
4
5
6
7
8
9
10
template <class ACE_SELECT_REACTOR_TOKEN> int
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::register_handler
(ACE_HANDLE handle,
ACE_Event_Handler *handler,
ACE_Reactor_Mask mask)
{
ACE_TRACE ("ACE_Select_Reactor_T::register_handler");
ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
return this->register_handler_i (handle, handler, mask);
}

3.2.2. register_handler_i 函数流程

ace/Select_Reactor_T.cpp register_handler 函数

 1
2
3
4
5
6
7
8
9
10
11
12
template <class ACE_SELECT_REACTOR_TOKEN> int
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::register_handler_i
(ACE_HANDLE handle,
ACE_Event_Handler *event_handler,
ACE_Reactor_Mask mask)
{
ACE_TRACE ("ACE_Select_Reactor_T::register_handler_i"); // Insert the <handle, event_handle> tuple into the Handler
// Repository.
return this->handler_rep_.bind (handle, event_handler, mask);
}

3.2.3. bind 函数

映射数据结构定义

行26实现了真正的关联操作,this->event_handlers_.bind (handle, event_handler, entry); 其中变量 event_handlers_ 在程序中定义为*map_type*, 在Unix下具体定义如下typedef ACE_Array_Base<value_type> map_type;,也即使用handle 句柄值作为数组的索引,实现了map的功能。在windows下使用了ACE_Hash_Map_Manager_Ex作为map实现的类, typedef ACE_Hash_Map_Manager_Ex<key_type,value_type, ACE_Hash<key_type>,std::equal_to<key_type>,ACE_Null_Mutex> map_type;,其中 key_type的定义为:typedefACE_HANDLE key_type;,另外value_type定义为 typedef ACE_Event_Handler * value_type;

ace/Select_Reactor_Base.cpp bind 函数

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// Bind the <ACE_Event_Handler *> to the <ACE_HANDLE>.
int
ACE_Select_Reactor_Handler_Repository::bind (ACE_HANDLE handle,
ACE_Event_Handler *event_handler,
ACE_Reactor_Mask mask)
{
ACE_TRACE ("ACE_Select_Reactor_Handler_Repository::bind"); if (event_handler == 0)
return -1; if (handle == ACE_INVALID_HANDLE)
handle = event_handler->get_handle (); if (this->invalid_handle (handle))
return -1; // Is this handle already in the Reactor?
bool existing_handle = false; #if defined (ACE_WIN32) map_type::ENTRY * entry = 0; int const result =
this->event_handlers_.bind (handle, event_handler, entry);

if (result == -1)
{
return -1;
}
else if (result == 1) // Entry already exists.
{
// Cannot use a different handler for an existing handle.
if (event_handler != entry->item ())
{
return -1;
}
else
{
// Remember that this handle is already registered in the
// Reactor.
existing_handle = true;
}
} #else // Check if this handle is already registered.
ACE_Event_Handler * const current_handler =
this->event_handlers_[handle]; if (current_handler)
{
// Cannot use a different handler for an existing handle.
if (current_handler != event_handler)
return -1; // Remember that this handle is already registered in the
// Reactor.
existing_handle = true;
} this->event_handlers_[handle] = event_handler; if (this->max_handlep1_ < handle + 1)
this->max_handlep1_ = handle + 1; #endif /* ACE_WIN32 */ if (this->select_reactor_.is_suspended_i (handle))
{
this->select_reactor_.bit_ops (handle,
mask,
this->select_reactor_.suspend_set_,
ACE_Reactor::ADD_MASK);
}
else
{
this->select_reactor_.bit_ops (handle,
mask,
this->select_reactor_.wait_set_,
ACE_Reactor::ADD_MASK); // Note the fact that we've changed the state of the <wait_set_>,
// which is used by the dispatching loop to determine whether it can
// keep going or if it needs to reconsult select().
// this->select_reactor_.state_changed_ = 1;
} // If new entry, call add_reference() if needed.
if (!existing_handle)
event_handler->add_reference (); return 0;
}

3.3. handler移除

3.3.1. remove_handler 函数流程

ace/Select_Reactor_T.cpp remove_handler 函数

1
2
3
4
5
6
7
8
9
template <class ACE_SELECT_REACTOR_TOKEN> int
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::remove_handler
(ACE_HANDLE handle,
ACE_Reactor_Mask mask)
{
ACE_TRACE ("ACE_Select_Reactor_T::remove_handler");
ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
return this->remove_handler_i (handle, mask);
}

3.3.2. remove_handler_i 函数流程

ace/Select_Reactor_T.cpp remove_handler_i 函数

 1
2
3
4
5
6
7
8
9
10
template <class ACE_SELECT_REACTOR_TOKEN> int
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::remove_handler_i
(ACE_HANDLE handle,
ACE_Reactor_Mask mask)
{
ACE_TRACE ("ACE_Select_Reactor_T::remove_handler_i"); // Unbind this handle.
return this->handler_rep_.unbind (handle, mask);
}

3.3.3. unbind 函数

ace/Select_Reactor_Base.cpp unbind 函数

  1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
int
ACE_Select_Reactor_Handler_Repository::unbind (
ACE_HANDLE handle,
map_type::iterator pos,
ACE_Reactor_Mask mask)
{
ACE_TRACE ("ACE_Select_Reactor_Handler_Repository::unbind"); // Retrieve event handler before unbinding it from the map. The
// iterator pointing to it will no longer be valid once the handler
// is unbound.
ACE_Event_Handler * const event_handler =
(pos == this->event_handlers_.end ()
? 0
: ACE_SELECT_REACTOR_EVENT_HANDLER (pos)); // Clear out the <mask> bits in the Select_Reactor's wait_set.
this->select_reactor_.bit_ops (handle,
mask,
this->select_reactor_.wait_set_,
ACE_Reactor::CLR_MASK); // And suspend_set.
this->select_reactor_.bit_ops (handle,
mask,
this->select_reactor_.suspend_set_,
ACE_Reactor::CLR_MASK); // Note the fact that we've changed the state of the <wait_set_>,
// which is used by the dispatching loop to determine whether it can
// keep going or if it needs to reconsult select().
// this->select_reactor_.state_changed_ = 1; // If there are no longer any outstanding events on this <handle>
// then we can totally shut down the Event_Handler. bool const has_any_wait_mask =
(this->select_reactor_.wait_set_.rd_mask_.is_set (handle)
|| this->select_reactor_.wait_set_.wr_mask_.is_set (handle)
|| this->select_reactor_.wait_set_.ex_mask_.is_set (handle));
bool const has_any_suspend_mask =
(this->select_reactor_.suspend_set_.rd_mask_.is_set (handle)
|| this->select_reactor_.suspend_set_.wr_mask_.is_set (handle)
|| this->select_reactor_.suspend_set_.ex_mask_.is_set (handle)); bool complete_removal = false; if (!has_any_wait_mask && !has_any_suspend_mask)
{
#if defined (ACE_WIN32)
if (event_handler != 0 && this->event_handlers_.unbind (pos) == -1)
return -1; // Should not happen!
#else
this->event_handlers_[handle] = 0; if (this->max_handlep1_ == handle + 1)
{
// We've deleted the last entry, so we need to figure out
// the last valid place in the array that is worth looking
// at.
ACE_HANDLE const wait_rd_max =
this->select_reactor_.wait_set_.rd_mask_.max_set ();
ACE_HANDLE const wait_wr_max =
this->select_reactor_.wait_set_.wr_mask_.max_set ();
ACE_HANDLE const wait_ex_max =
this->select_reactor_.wait_set_.ex_mask_.max_set (); ACE_HANDLE const suspend_rd_max =
this->select_reactor_.suspend_set_.rd_mask_.max_set ();
ACE_HANDLE const suspend_wr_max =
this->select_reactor_.suspend_set_.wr_mask_.max_set ();
ACE_HANDLE const suspend_ex_max =
this->select_reactor_.suspend_set_.ex_mask_.max_set (); // Compute the maximum of six values.
this->max_handlep1_ = wait_rd_max;
if (this->max_handlep1_ < wait_wr_max)
this->max_handlep1_ = wait_wr_max;
if (this->max_handlep1_ < wait_ex_max)
this->max_handlep1_ = wait_ex_max; if (this->max_handlep1_ < suspend_rd_max)
this->max_handlep1_ = suspend_rd_max;
if (this->max_handlep1_ < suspend_wr_max)
this->max_handlep1_ = suspend_wr_max;
if (this->max_handlep1_ < suspend_ex_max)
this->max_handlep1_ = suspend_ex_max; ++this->max_handlep1_;
} #endif /* ACE_WIN32 */ // The handle has been completely removed.
complete_removal = true;
} if (event_handler == 0)
return -1; bool const requires_reference_counting =
event_handler->reference_counting_policy ().value () ==
ACE_Event_Handler::Reference_Counting_Policy::ENABLED; // Close down the <Event_Handler> unless we've been instructed not
// to.
if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::DONT_CALL) == 0)
(void) event_handler->handle_close (handle, mask); // Call remove_reference() if the removal is complete and reference
// counting is needed.
if (complete_removal && requires_reference_counting)
{
(void) event_handler->remove_reference ();
} return 0;
}

警告

remove_handler 函数在后续调用 unbind 函数中,会触发对 handle_close 行107-108 的调用,需要注意,否则在 handle_close 函数中 使用 remove_handler 如果没有设置 DONT_CALL 标志,会导致 handle_close 的循环调用。

3.4. handler暂停

3.4.1. suspend_handler 函数

ace/Select_Reactor_T.cpp suspend_handler 函数

1
2
3
4
5
6
7
template <class ACE_SELECT_REACTOR_TOKEN> int
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::suspend_handler (ACE_HANDLE handle)
{
ACE_TRACE ("ACE_Select_Reactor_T::suspend_handler");
ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
return this->suspend_i (handle);
}

3.4.2. suspend_i 函数

ace/Select_Reactor_T.cpp suspend_i 函数

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
template <class ACE_SELECT_REACTOR_TOKEN> int
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::suspend_i (ACE_HANDLE handle)
{
ACE_TRACE ("ACE_Select_Reactor_T::suspend_i");
if (this->handler_rep_.find (handle) == 0)
return -1; if (this->wait_set_.rd_mask_.is_set (handle))
{
this->suspend_set_.rd_mask_.set_bit (handle);
this->wait_set_.rd_mask_.clr_bit (handle);
}
if (this->wait_set_.wr_mask_.is_set (handle))
{
this->suspend_set_.wr_mask_.set_bit (handle);
this->wait_set_.wr_mask_.clr_bit (handle);
}
if (this->wait_set_.ex_mask_.is_set (handle))
{
this->suspend_set_.ex_mask_.set_bit (handle);
this->wait_set_.ex_mask_.clr_bit (handle);
} // Kobi: we need to remove that handle from the
// dispatch set as well. We use that function with all the relevant
// masks - rd/wr/ex - all the mask. it is completely suspended
this->clear_dispatch_mask (handle, ACE_Event_Handler::RWE_MASK);
return 0;
}

3.5. handler恢复

3.5.1. resume_handler 函数

ace/Select_Reactor_T.cpp resume_handler 函数

1
2
3
4
5
6
7
template <class ACE_SELECT_REACTOR_TOKEN> int
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::resume_handler (ACE_HANDLE handle)
{
ACE_TRACE ("ACE_Select_Reactor_T::resume_handler");
ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
return this->resume_i (handle);
}

3.5.2. resume_handler_i 函数

ace/Select_Reactor_T.cpp resume_handler_i 函数

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
template <class ACE_SELECT_REACTOR_TOKEN> int
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::resume_i (ACE_HANDLE handle)
{
ACE_TRACE ("ACE_Select_Reactor_T::resume_i");
if (this->handler_rep_.find (handle) == 0)
return -1; if (this->suspend_set_.rd_mask_.is_set (handle))
{
this->wait_set_.rd_mask_.set_bit (handle);
this->suspend_set_.rd_mask_.clr_bit (handle);
}
if (this->suspend_set_.wr_mask_.is_set (handle))
{
this->wait_set_.wr_mask_.set_bit (handle);
this->suspend_set_.wr_mask_.clr_bit (handle);
}
if (this->suspend_set_.ex_mask_.is_set (handle))
{
this->wait_set_.ex_mask_.set_bit (handle);
this->suspend_set_.ex_mask_.clr_bit (handle);
}
return 0;
}

I/O Handler的管理(3)的更多相关文章

  1. 爬虫学习(五)——使用handler管理器对象进行数据爬取的步骤

    # 使用管理器对象进行爬取数据的步骤 import urllib.requesturl = "https://www.baidu.com/"# 创建handler的管理器对象han ...

  2. Android 线程通讯类Handler

    handler是线程通讯工具类.用于传递消息.它有两个队列: 1.消息队列 2.线程队列 消息队列使用sendMessage和HandleMessage的组合来发送和处理消息. 线程队列类似一段代码, ...

  3. Android——线程通讯类Handler(转)

    原文地址:http://uule.iteye.com/blog/1705951 handler是线程通讯工具类.用于传递消息.它有两个队列:1.消息队列2.线程队列 消息队列使用sendMessage ...

  4. 昨天刚看了Handler和HandlerThread这个东西,不明白为什么要用这么复杂的东西,而且Handler直接post的话好像还不是子线程运行。那我再开发的时候直接用Thread行不行?两个有什么区别?

    Handler就是android中一个机制,主要是考虑到线程安全的! Handler是可以实现线程间通信的,LZ知道Android的UI线程不安全的吧,也就是说不可以在UI线程以外的其他线程对UI进行 ...

  5. STM32启动文件详细解析(V3.5.0) 以:startup_stm32f10x_hd.s为例

    我用的是IAR,这个貌似是MDK的,不过很有用,大家可以看一下 ;* 文件名 : startup_stm32f10x_hd.s ;* 库版本 : V3.5.0 ;* 说明: 此文件为STM32F10x ...

  6. stm32f系列单片机startup_stm32fxxx.s文件说明(转)

    * 文件名          : startup_stm32f10x_hd.s;* 库版本           : V3.5.0;* 说明:             此文件为STM32F10x高密度设 ...

  7. 浅析Android中的消息机制(转)

    原博客地址:http://blog.csdn.net/liuhe688/article/details/6407225 在分析Android消息机制之前,我们先来看一段代码: public class ...

  8. stm32启动文件 startup_stm32f10x_hd.s

    ;* 文件名          : startup_stm32f10x_hd.s;* 库版本           : V3.5.0;* 说明:             此文件为STM32F10x高密度 ...

  9. 浅析Android中的消息机制(转)

    在分析Android消息机制之前,我们先来看一段代码: public class MainActivity extends Activity implements View.OnClickListen ...

随机推荐

  1. java中equals以及==的用法(简单介绍)

    简单介绍 equals方法是java.lang.Object类的方法 有两种用法说明: 一.对于字符串变量来说,使用“==”和“equals()”方法比较字符串时,其比较方法不同. 1.“==”比较两 ...

  2. 【洛谷P2426】删数

    删数 题目链接 一道裸的区间DP,f[l][r]表示剩下区间[l,r]时的最大价值 可以由f[1~l-1][r]和f[l][r+1~n]转移过来 详见代码: #include<algorithm ...

  3. mysql 综合

    一.库操作 二.表操作 1.存储引擎介绍 show engines; 查看数据库支持的引擎 MySQL 使用 InnoDB 指定表类型/存储引擎 create table t1(id int)engi ...

  4. LeetCode2.两数相加 JavaScript

    给定两个非空链表来表示两个非负整数.位数按照逆序方式存储,它们的每个节点只存储单个数字.将两数相加返回一个新的链表. 你可以假设除了数字 0 之外,这两个数字都不会以零开头. 示例: 输入:(2 -& ...

  5. React Router 4 的使用(2)

    Route Rendering Props 对于给定的路由如何渲染组件,有三种选项:component.render.children.你可以查看 <Route> 的文档来获取更多的信息, ...

  6. Openresty最佳案例 | 第3篇:Openresty的安装

    转载请标明出处: http://blog.csdn.net/forezp/article/details/78616645 本文出自方志朋的博客 我的服务器为一台全新的centos 7的服务器,所以从 ...

  7. ATK 设计框架 之 Atk.CustomExpression

    在ATK-DataPortal框架中的xxxHandel中常用到的一种类型,形如: 1.protected virtual D ItemHandle(D item, Func<E, E> ...

  8. Hibernate知识点小结汇总

    Hibernate部分 1.为什么要使用Hibernate开发你的项目呢?Hibernate的开发流程是怎么样的? 为什么要使用 ①.对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复 ...

  9. JetBrains 授权服务器(License Server):

    JetBrains 授权服务器(License Server): https://www.imsxm.com/jetbrains-license-server.html

  10. MySQL——用户与密码

    mysql安装完成之后,在/var/log/mysqld.log文件中给root生成了一个默认密码.通过下面的方式找到root默认密码,然后登录mysql进行修改: grep 'temporary p ...