Openrefine mysql_MySQL内核技术之"线程操作"

预处理

当一个新的连接进来时,MySQL会创建对应的thread(pfs.cc):

/**

Implementation of the thread instrumentation interface.

@sa PSI_v1::spawn_thread.

*/

int pfs_spawn_thread_v1(PSI_thread_key key,

my_thread_handle *thread, const my_thread_attr_t *attr,

void *(*start_routine)(void*), void *arg)

{

PFS_spawn_thread_arg *psi_arg;

PFS_thread *parent;

/* psi_arg can not be global, and can not be a local variable. */

psi_arg= (PFS_spawn_thread_arg*) my_malloc(PSI_NOT_INSTRUMENTED,

sizeof(PFS_spawn_thread_arg),

MYF(MY_WME));

if (unlikely(psi_arg == NULL))

return EAGAIN;

psi_arg->m_child_key= key;

psi_arg->m_child_identity= (arg ? arg : thread);

psi_arg->m_user_start_routine= start_routine;

psi_arg->m_user_arg= arg;

parent= my_thread_get_THR_PFS();

if (parent != NULL)

{

/*

Make a copy of the parent attributes.

This is required, because instrumentation for this thread (the parent)

may be destroyed before the child thread instrumentation is created.

*/

psi_arg->m_thread_internal_id= parent->m_thread_internal_id;

memcpy(psi_arg->m_username, parent->m_username, sizeof(psi_arg->m_username));

psi_arg->m_username_length= parent->m_username_length;

memcpy(psi_arg->m_hostname, parent->m_hostname, sizeof(psi_arg->m_hostname));

psi_arg->m_hostname_length= parent->m_hostname_length;

}

else

{

psi_arg->m_thread_internal_id= 0;

psi_arg->m_username_length= 0;

psi_arg->m_hostname_length= 0;

}

int result= my_thread_create(thread, attr, pfs_spawn_thread, psi_arg);

if (unlikely(result != 0))

my_free(psi_arg);

return result;

}

注意上面代码中最后的位置: my_thread_create(thread, attr, pfs_spawn_thread, psi_arg);这个函数直接调用pthread_create(&thread->thread, attr, func, arg)创建pthead。

这里最重要的事情是把当前thread的执行环境传到新的thread。所以上面代码前半部分都是在做这个事情。让我们看一下都需要传入哪些上下文。参数psi_arg就是要传入的上下文。开始用my_malloc创建,最后用my_free销毁。中间是对psi_arg进行赋值。

和当前线程有关的是parent= my_thread_get_THR_PFS()。然后把需要的parent内容取出来并赋值给psi_arg:

/*

Make a copy of the parent attributes.

This is required, because instrumentation for this thread (the parent)

may be destroyed before the child thread instrumentation is created.

*/

psi_arg->m_thread_internal_id= parent->m_thread_internal_id;

memcpy(psi_arg->m_username, parent->m_username, sizeof(psi_arg->m_username));

psi_arg->m_username_length= parent->m_username_length;

memcpy(psi_arg->m_hostname, parent->m_hostname, sizeof(psi_arg->m_hostname));

psi_arg->m_hostname_length= parent->m_hostname_length;

主要是对三个变量赋值:m_thread_internal_id,m_username,m_hostname。

生成PFS_thread

从上面可以看到,生成的thread具体执行的pfs_spawn_thread函数,其内容如下:

extern "C" void* pfs_spawn_thread(void *arg)

{

PFS_spawn_thread_arg *typed_arg= (PFS_spawn_thread_arg*) arg;

void *user_arg;

void *(*user_start_routine)(void*);

PFS_thread *pfs;

/* First, attach instrumentation to this newly created pthread. */

PFS_thread_class *klass= find_thread_class(typed_arg->m_child_key);

if (likely(klass != NULL))

{

pfs= create_thread(klass, typed_arg->m_child_identity, 0);

if (likely(pfs != NULL))

{

pfs->m_thread_os_id= my_thread_os_id();

clear_thread_account(pfs);

pfs->m_parent_thread_internal_id= typed_arg->m_thread_internal_id;

memcpy(pfs->m_username, typed_arg->m_username, sizeof(pfs->m_username));

pfs->m_username_length= typed_arg->m_username_length;

memcpy(pfs->m_hostname, typed_arg->m_hostname, sizeof(pfs->m_hostname));

pfs->m_hostname_length= typed_arg->m_hostname_length;

set_thread_account(pfs);

}

}

else

{

pfs= NULL;

}

std::cout << "my_thread_set_THR_PFS in pfs_spawn_thread, value: " << pfs << std::endl;

my_thread_set_THR_PFS(pfs);

/*

Secondly, free the memory allocated in spawn_thread_v1().

It is preferable to do this before invoking the user

routine, to avoid memory leaks at shutdown, in case

the server exits without waiting for this thread.

*/

user_start_routine= typed_arg->m_user_start_routine;

user_arg= typed_arg->m_user_arg;

my_free(typed_arg);

/* Then, execute the user code for this thread. */

(*user_start_routine)(user_arg);

return NULL;

}

代码改动

由于开发原因,我加入了一个boost线程池,那么从原始线程产生任务塞入boost线程池中的时候,需要做类似的操作,即要传入一个psi_arg参数。因为PSI是performance schema,所以其本身对执行并没有影响,我们可以把子线程的PSI设置为NULL。在psi.h中,我们可以看到:

/**

Instrumented thread key.

To instrument a thread, a thread key must be obtained

using @c register_thread.

Using a zero key always disable the instrumentation.

*/

typedef unsigned int PSI_thread_key;

获取当前的pfs:

/**

Implementation of the thread instrumentation interface.

@sa PSI_v1::get_thread_id.

*/

PSI_thread*

pfs_get_thread_v1(void)

{

PFS_thread *pfs= my_thread_get_THR_PFS();

return reinterpret_cast (pfs);

}

注意,不能直接用my_thread_get_THR_PFS()获取,因为其为static函数,只能用于本文件使用。同理设置pfs:

/**

Implementation of the thread instrumentation interface.

@sa PSI_v1::set_thread.

*/

void pfs_set_thread_v1(PSI_thread* thread)

{

PFS_thread *pfs= reinterpret_cast (thread);

my_thread_set_THR_PFS(pfs);

std::cout << "my_thread_set_THR_PFS in pfs_set_thread_v1, value: "<< pfs << std::endl;

}

附录:

定义的PSI结构(psi.h):

/**

Performance Schema Interface, version 1.

@since PSI_VERSION_1

*/

struct PSI_v1

{

/** @sa register_mutex_v1_t. */

register_mutex_v1_t register_mutex;

/** @sa register_rwlock_v1_t. */

register_rwlock_v1_t register_rwlock;

/** @sa register_cond_v1_t. */

register_cond_v1_t register_cond;

/** @sa register_thread_v1_t. */

register_thread_v1_t register_thread;

/** @sa register_file_v1_t. */

register_file_v1_t register_file;

/** @sa register_stage_v1_t. */

register_stage_v1_t register_stage;

/** @sa register_statement_v1_t. */

register_statement_v1_t register_statement;

/** @sa register_socket_v1_t. */

register_socket_v1_t register_socket;

/** @sa init_mutex_v1_t. */

init_mutex_v1_t init_mutex;

/** @sa destroy_mutex_v1_t. */

destroy_mutex_v1_t destroy_mutex;

/** @sa init_rwlock_v1_t. */

init_rwlock_v1_t init_rwlock;

/** @sa destroy_rwlock_v1_t. */

destroy_rwlock_v1_t destroy_rwlock;

/** @sa init_cond_v1_t. */

init_cond_v1_t init_cond;

/** @sa destroy_cond_v1_t. */

destroy_cond_v1_t destroy_cond;

/** @sa init_socket_v1_t. */

init_socket_v1_t init_socket;

/** @sa destroy_socket_v1_t. */

destroy_socket_v1_t destroy_socket;

/** @sa get_table_share_v1_t. */

get_table_share_v1_t get_table_share;

/** @sa release_table_share_v1_t. */

release_table_share_v1_t release_table_share;

/** @sa drop_table_share_v1_t. */

drop_table_share_v1_t drop_table_share;

/** @sa open_table_v1_t. */

open_table_v1_t open_table;

/** @sa unbind_table_v1_t. */

unbind_table_v1_t unbind_table;

/** @sa rebind_table_v1_t. */

rebind_table_v1_t rebind_table;

/** @sa close_table_v1_t. */

close_table_v1_t close_table;

/** @sa create_file_v1_t. */

create_file_v1_t create_file;

/** @sa spawn_thread_v1_t. */

spawn_thread_v1_t spawn_thread;

/** @sa new_thread_v1_t. */

new_thread_v1_t new_thread;

/** @sa set_thread_id_v1_t. */

set_thread_id_v1_t set_thread_id;

/** @sa set_thread_THD_v1_t. */

set_thread_THD_v1_t set_thread_THD;

/** @sa set_thread_os_id_v1_t. */

set_thread_os_id_v1_t set_thread_os_id;

/** @sa get_thread_v1_t. */

get_thread_v1_t get_thread;

/** @sa set_thread_user_v1_t. */

set_thread_user_v1_t set_thread_user;

/** @sa set_thread_account_v1_t. */

set_thread_account_v1_t set_thread_account;

/** @sa set_thread_db_v1_t. */

set_thread_db_v1_t set_thread_db;

/** @sa set_thread_command_v1_t. */

set_thread_command_v1_t set_thread_command;

/** @sa set_connection_type_v1_t. */

set_connection_type_v1_t set_connection_type;

/** @sa set_thread_start_time_v1_t. */

set_thread_start_time_v1_t set_thread_start_time;

/** @sa set_thread_state_v1_t. */

set_thread_state_v1_t set_thread_state;

/** @sa set_thread_info_v1_t. */

set_thread_info_v1_t set_thread_info;

/** @sa set_thread_v1_t. */

set_thread_v1_t set_thread;

/** @sa delete_current_thread_v1_t. */

delete_current_thread_v1_t delete_current_thread;

/** @sa delete_thread_v1_t. */

delete_thread_v1_t delete_thread;

/** @sa get_thread_file_name_locker_v1_t. */

get_thread_file_name_locker_v1_t get_thread_file_name_locker;

/** @sa get_thread_file_stream_locker_v1_t. */

get_thread_file_stream_locker_v1_t get_thread_file_stream_locker;

/** @sa get_thread_file_descriptor_locker_v1_t. */

get_thread_file_descriptor_locker_v1_t get_thread_file_descriptor_locker;

/** @sa unlock_mutex_v1_t. */

unlock_mutex_v1_t unlock_mutex;

/** @sa unlock_rwlock_v1_t. */

unlock_rwlock_v1_t unlock_rwlock;

/** @sa signal_cond_v1_t. */

signal_cond_v1_t signal_cond;

/** @sa broadcast_cond_v1_t. */

broadcast_cond_v1_t broadcast_cond;

/** @sa start_idle_wait_v1_t. */

start_idle_wait_v1_t start_idle_wait;

/** @sa end_idle_wait_v1_t. */

end_idle_wait_v1_t end_idle_wait;

/** @sa start_mutex_wait_v1_t. */

start_mutex_wait_v1_t start_mutex_wait;

/** @sa end_mutex_wait_v1_t. */

end_mutex_wait_v1_t end_mutex_wait;

/** @sa start_rwlock_rdwait_v1_t. */

start_rwlock_rdwait_v1_t start_rwlock_rdwait;

/** @sa end_rwlock_rdwait_v1_t. */

end_rwlock_rdwait_v1_t end_rwlock_rdwait;

/** @sa start_rwlock_wrwait_v1_t. */

start_rwlock_wrwait_v1_t start_rwlock_wrwait;

/** @sa end_rwlock_wrwait_v1_t. */

end_rwlock_wrwait_v1_t end_rwlock_wrwait;

/** @sa start_cond_wait_v1_t. */

start_cond_wait_v1_t start_cond_wait;

/** @sa end_cond_wait_v1_t. */

end_cond_wait_v1_t end_cond_wait;

/** @sa start_table_io_wait_v1_t. */

start_table_io_wait_v1_t start_table_io_wait;

/** @sa end_table_io_wait_v1_t. */

end_table_io_wait_v1_t end_table_io_wait;

/** @sa start_table_lock_wait_v1_t. */

start_table_lock_wait_v1_t start_table_lock_wait;

/** @sa end_table_lock_wait_v1_t. */

end_table_lock_wait_v1_t end_table_lock_wait;

/** @sa start_file_open_wait_v1_t. */

start_file_open_wait_v1_t start_file_open_wait;

/** @sa end_file_open_wait_v1_t. */

end_file_open_wait_v1_t end_file_open_wait;

/** @sa end_file_open_wait_and_bind_to_descriptor_v1_t. */

end_file_open_wait_and_bind_to_descriptor_v1_t

end_file_open_wait_and_bind_to_descriptor;

/** @sa end_temp_file_open_wait_and_bind_to_descriptor_v1_t. */

end_temp_file_open_wait_and_bind_to_descriptor_v1_t

end_temp_file_open_wait_and_bind_to_descriptor;

/** @sa start_file_wait_v1_t. */

start_file_wait_v1_t start_file_wait;

/** @sa end_file_wait_v1_t. */

end_file_wait_v1_t end_file_wait;

/** @sa start_file_close_wait_v1_t. */

start_file_close_wait_v1_t start_file_close_wait;

/** @sa end_file_close_wait_v1_t. */

end_file_close_wait_v1_t end_file_close_wait;

/** @sa start_stage_v1_t. */

start_stage_v1_t start_stage;

/** @sa get_current_stage_progress_v1_t. */

get_current_stage_progress_v1_t get_current_stage_progress;

/** @sa end_stage_v1_t. */

end_stage_v1_t end_stage;

/** @sa get_thread_statement_locker_v1_t. */

get_thread_statement_locker_v1_t get_thread_statement_locker;

/** @sa refine_statement_v1_t. */

refine_statement_v1_t refine_statement;

/** @sa start_statement_v1_t. */

start_statement_v1_t start_statement;

/** @sa set_statement_text_v1_t. */

set_statement_text_v1_t set_statement_text;

/** @sa set_statement_lock_time_t. */

set_statement_lock_time_t set_statement_lock_time;

/** @sa set_statement_rows_sent_t. */

set_statement_rows_sent_t set_statement_rows_sent;

/** @sa set_statement_rows_examined_t. */

set_statement_rows_examined_t set_statement_rows_examined;

/** @sa inc_statement_created_tmp_disk_tables. */

inc_statement_created_tmp_disk_tables_t inc_statement_created_tmp_disk_tables;

/** @sa inc_statement_created_tmp_tables. */

inc_statement_created_tmp_tables_t inc_statement_created_tmp_tables;

/** @sa inc_statement_select_full_join. */

inc_statement_select_full_join_t inc_statement_select_full_join;

/** @sa inc_statement_select_full_range_join. */

inc_statement_select_full_range_join_t inc_statement_select_full_range_join;

/** @sa inc_statement_select_range. */

inc_statement_select_range_t inc_statement_select_range;

/** @sa inc_statement_select_range_check. */

inc_statement_select_range_check_t inc_statement_select_range_check;

/** @sa inc_statement_select_scan. */

inc_statement_select_scan_t inc_statement_select_scan;

/** @sa inc_statement_sort_merge_passes. */

inc_statement_sort_merge_passes_t inc_statement_sort_merge_passes;

/** @sa inc_statement_sort_range. */

inc_statement_sort_range_t inc_statement_sort_range;

/** @sa inc_statement_sort_rows. */

inc_statement_sort_rows_t inc_statement_sort_rows;

/** @sa inc_statement_sort_scan. */

inc_statement_sort_scan_t inc_statement_sort_scan;

/** @sa set_statement_no_index_used. */

set_statement_no_index_used_t set_statement_no_index_used;

/** @sa set_statement_no_good_index_used. */

set_statement_no_good_index_used_t set_statement_no_good_index_used;

/** @sa end_statement_v1_t. */

end_statement_v1_t end_statement;

/** @sa get_thread_transaction_locker_v1_t. */

get_thread_transaction_locker_v1_t get_thread_transaction_locker;

/** @sa start_transaction_v1_t. */

start_transaction_v1_t start_transaction;

/** @sa set_transaction_xid_v1_t. */

set_transaction_xid_v1_t set_transaction_xid;

/** @sa set_transaction_xa_state_v1_t. */

set_transaction_xa_state_v1_t set_transaction_xa_state;

/** @sa set_transaction_gtid_v1_t. */

set_transaction_gtid_v1_t set_transaction_gtid;

/** @sa set_transaction_trxid_v1_t. */

set_transaction_trxid_v1_t set_transaction_trxid;

/** @sa inc_transaction_savepoints_v1_t. */

inc_transaction_savepoints_v1_t inc_transaction_savepoints;

/** @sa inc_transaction_rollback_to_savepoint_v1_t. */

inc_transaction_rollback_to_savepoint_v1_t inc_transaction_rollback_to_savepoint;

/** @sa inc_transaction_release_savepoint_v1_t. */

inc_transaction_release_savepoint_v1_t inc_transaction_release_savepoint;

/** @sa end_transaction_v1_t. */

end_transaction_v1_t end_transaction;

/** @sa start_socket_wait_v1_t. */

start_socket_wait_v1_t start_socket_wait;

/** @sa end_socket_wait_v1_t. */

end_socket_wait_v1_t end_socket_wait;

/** @sa set_socket_state_v1_t. */

set_socket_state_v1_t set_socket_state;

/** @sa set_socket_info_v1_t. */

set_socket_info_v1_t set_socket_info;

/** @sa set_socket_thread_owner_v1_t. */

set_socket_thread_owner_v1_t set_socket_thread_owner;

/** @sa create_prepared_stmt_v1_t. */

create_prepared_stmt_v1_t create_prepared_stmt;

/** @sa destroy_prepared_stmt_v1_t. */

destroy_prepared_stmt_v1_t destroy_prepared_stmt;

/** @sa reprepare_prepared_stmt_v1_t. */

reprepare_prepared_stmt_v1_t reprepare_prepared_stmt;

/** @sa execute_prepared_stmt_v1_t. */

execute_prepared_stmt_v1_t execute_prepared_stmt;

/** @sa digest_start_v1_t. */

digest_start_v1_t digest_start;

/** @sa digest_end_v1_t. */

digest_end_v1_t digest_end;

/** @sa set_thread_connect_attrs_v1_t. */

set_thread_connect_attrs_v1_t set_thread_connect_attrs;

/** @sa start_sp_v1_t. */

start_sp_v1_t start_sp;

/** @sa start_sp_v1_t. */

end_sp_v1_t end_sp;

/** @sa drop_sp_v1_t. */

drop_sp_v1_t drop_sp;

/** @sa get_sp_share_v1_t. */

get_sp_share_v1_t get_sp_share;

/** @sa release_sp_share_v1_t. */

release_sp_share_v1_t release_sp_share;

/** @sa register_memory_v1_t. */

register_memory_v1_t register_memory;

/** @sa memory_alloc_v1_t. */

memory_alloc_v1_t memory_alloc;

/** @sa memory_realloc_v1_t. */

memory_realloc_v1_t memory_realloc;

/** @sa memory_claim_v1_t. */

memory_claim_v1_t memory_claim;

/** @sa memory_free_v1_t. */

memory_free_v1_t memory_free;

unlock_table_v1_t unlock_table;

create_metadata_lock_v1_t create_metadata_lock;

set_metadata_lock_status_v1_t set_metadata_lock_status;

destroy_metadata_lock_v1_t destroy_metadata_lock;

start_metadata_wait_v1_t start_metadata_wait;

end_metadata_wait_v1_t end_metadata_wait;

};

该结构在psi.cc被赋值:

/**

Implementation of the instrumentation interface.

@sa PSI_v1.

*/

PSI_v1 PFS_v1=

{

pfs_register_mutex_v1,

pfs_register_rwlock_v1,

pfs_register_cond_v1,

pfs_register_thread_v1,

pfs_register_file_v1,

pfs_register_stage_v1,

pfs_register_statement_v1,

pfs_register_socket_v1,

pfs_init_mutex_v1,

pfs_destroy_mutex_v1,

pfs_init_rwlock_v1,

pfs_destroy_rwlock_v1,

pfs_init_cond_v1,

pfs_destroy_cond_v1,

pfs_init_socket_v1,

pfs_destroy_socket_v1,

pfs_get_table_share_v1,

pfs_release_table_share_v1,

pfs_drop_table_share_v1,

pfs_open_table_v1,

pfs_unbind_table_v1,

pfs_rebind_table_v1,

pfs_close_table_v1,

pfs_create_file_v1,

pfs_spawn_thread_v1,

pfs_new_thread_v1,

pfs_set_thread_id_v1,

pfs_set_thread_THD_v1,

pfs_set_thread_os_id_v1,

pfs_get_thread_v1,

pfs_set_thread_user_v1,

pfs_set_thread_account_v1,

pfs_set_thread_db_v1,

pfs_set_thread_command_v1,

pfs_set_connection_type_v1,

pfs_set_thread_start_time_v1,

pfs_set_thread_state_v1,

pfs_set_thread_info_v1,

pfs_set_thread_v1,

pfs_delete_current_thread_v1,

pfs_delete_thread_v1,

pfs_get_thread_file_name_locker_v1,

pfs_get_thread_file_stream_locker_v1,

pfs_get_thread_file_descriptor_locker_v1,

pfs_unlock_mutex_v1,

pfs_unlock_rwlock_v1,

pfs_signal_cond_v1,

pfs_broadcast_cond_v1,

pfs_start_idle_wait_v1,

pfs_end_idle_wait_v1,

pfs_start_mutex_wait_v1,

pfs_end_mutex_wait_v1,

pfs_start_rwlock_rdwait_v1,

pfs_end_rwlock_rdwait_v1,

pfs_start_rwlock_wrwait_v1,

pfs_end_rwlock_wrwait_v1,

pfs_start_cond_wait_v1,

pfs_end_cond_wait_v1,

pfs_start_table_io_wait_v1,

pfs_end_table_io_wait_v1,

pfs_start_table_lock_wait_v1,

pfs_end_table_lock_wait_v1,

pfs_start_file_open_wait_v1,

pfs_end_file_open_wait_v1,

pfs_end_file_open_wait_and_bind_to_descriptor_v1,

pfs_end_temp_file_open_wait_and_bind_to_descriptor_v1,

pfs_start_file_wait_v1,

pfs_end_file_wait_v1,

pfs_start_file_close_wait_v1,

pfs_end_file_close_wait_v1,

pfs_start_stage_v1,

pfs_get_current_stage_progress_v1,

pfs_end_stage_v1,

pfs_get_thread_statement_locker_v1,

pfs_refine_statement_v1,

pfs_start_statement_v1,

pfs_set_statement_text_v1,

pfs_set_statement_lock_time_v1,

pfs_set_statement_rows_sent_v1,

pfs_set_statement_rows_examined_v1,

pfs_inc_statement_created_tmp_disk_tables_v1,

pfs_inc_statement_created_tmp_tables_v1,

pfs_inc_statement_select_full_join_v1,

pfs_inc_statement_select_full_range_join_v1,

pfs_inc_statement_select_range_v1,

pfs_inc_statement_select_range_check_v1,

pfs_inc_statement_select_scan_v1,

pfs_inc_statement_sort_merge_passes_v1,

pfs_inc_statement_sort_range_v1,

pfs_inc_statement_sort_rows_v1,

pfs_inc_statement_sort_scan_v1,

pfs_set_statement_no_index_used_v1,

pfs_set_statement_no_good_index_used_v1,

pfs_end_statement_v1,

pfs_get_thread_transaction_locker_v1,

pfs_start_transaction_v1,

pfs_set_transaction_xid_v1,

pfs_set_transaction_xa_state_v1,

pfs_set_transaction_gtid_v1,

pfs_set_transaction_trxid_v1,

pfs_inc_transaction_savepoints_v1,

pfs_inc_transaction_rollback_to_savepoint_v1,

pfs_inc_transaction_release_savepoint_v1,

pfs_end_transaction_v1,

pfs_start_socket_wait_v1,

pfs_end_socket_wait_v1,

pfs_set_socket_state_v1,

pfs_set_socket_info_v1,

pfs_set_socket_thread_owner_v1,

pfs_create_prepared_stmt_v1,

pfs_destroy_prepared_stmt_v1,

pfs_reprepare_prepared_stmt_v1,

pfs_execute_prepared_stmt_v1,

pfs_digest_start_v1,

pfs_digest_end_v1,

pfs_set_thread_connect_attrs_v1,

pfs_start_sp_v1,

pfs_end_sp_v1,

pfs_drop_sp_v1,

pfs_get_sp_share_v1,

pfs_release_sp_share_v1,

pfs_register_memory_v1,

pfs_memory_alloc_v1,

pfs_memory_realloc_v1,

pfs_memory_claim_v1,

pfs_memory_free_v1,

pfs_unlock_table_v1,

pfs_create_metadata_lock_v1,

pfs_set_metadata_lock_status_v1,

pfs_destroy_metadata_lock_v1,

pfs_start_metadata_wait_v1,

pfs_end_metadata_wait_v1

};

每一个值都是一个函数。感兴趣的可以去看对应实现。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值