main主函数

/home/id/lua.lua
/home/id/lua-c/lua.lua
/home/id/lua-c/metatable.lua
/home/id/lua-c/1.lua

int main(int argc, char **argv) {
return main_cmdline(argc, argv);
}
main_cmdline函数
int main_cmdline(int argc, char **argv) {
//设置底盘的选项
opts = chassis_options_new();
chassis_frontend_set_chassis_options(frontend, opts);
main_entries = chassis_options_to_g_option_entries(opts); //src\chassis-keyfile.c
chassis_keyfile_to_options(frontend->keyfile, "mysql-proxy", main_entries) //src\mysql-proxy-cli.c
//得到用户输入的/usr/local/wm/mysql-proxy/bin/mysql-proxy --defaults-file=/usr/local/wm/mysql-proxy/conf/source_wtf.cnf
//中的defaults-file
if (chassis_frontend_init_base_options(option_ctx, &argc, &argv, &(frontend->print_version), &(frontend->default_file), &gerr)) { } if (frontend->default_file) {
if (!(frontend->keyfile = chassis_frontend_open_config_file(frontend->default_file, &gerr))) {
g_log_dbproxy(g_critical, "loading config from '%s' failed: %s", frontend->default_file, gerr->message);
exit;
}
}
//得到defaults-file中的参数
if (frontend->keyfile) {
if (chassis_keyfile_to_options(frontend->keyfile, "mysql-proxy", main_entries)) {
GOTO_EXIT(EXIT_FAILURE);
}
} //加载插件
if (chassis_frontend_load_plugins(srv->modules, frontend->plugin_dir, frontend->plugin_names)) { } //初始化插件选项
chassis_frontend_init_plugins(srv->modules, option_ctx, &argc, &argv, frontend->keyfile, "mysql-proxy", srv->base_dir, &gerr)) { } //启动多个线程, 并设置回调函数chassis_event_handle, 使用libevent
if (chassis_mainloop(srv)) {
/* looks like we failed */
g_log_dbproxy(g_critical, "Failure from chassis_mainloop. Shutting down");
exit;
}
}

chassis_options_new
位置:src\chassis-options.c

/**
* create a command-line option
*/
chassis_options_t *chassis_options_new() {
chassis_options_t *opt; opt = g_slice_new0(chassis_options_t); return opt;
}

chassis_frontend_set_chassis_options
位置:src\mysql-proxy-cli.c

/**
* setup the options of the chassis
*/
int chassis_frontend_set_chassis_options(chassis_frontend_t *frontend, chassis_options_t *opts) {
chassis_options_add(opts, "verbose-shutdown", , , G_OPTION_ARG_NONE, &(frontend->verbose_shutdown), "Always log the exit code when shutting down", NULL, NULL, NULL, );
}

chassis_options_add
位置:src\chassis-options.c

int chassis_options_add(chassis_options_t *opts,
const char *long_name,
gchar short_name,
gint flags,
GOptionArg arg,
gpointer arg_data,
const char *description,
const char *arg_description,
chas_opt_assign_hook assign_hook,
chas_opt_show_hook show_hook,
gint opt_property) {
chassis_option_t *opt; opt = chassis_option_new();
if ( != chassis_option_set(opt,
long_name,
short_name,
flags,
arg,
arg_data,
description,
arg_description,
assign_hook,
show_hook,
opt_property) ||
!= chassis_options_add_option(opts, opt)) {
chassis_option_free(opt);
return -;
} else {
return ;
}
}

chassis_option_set
位置:src\chassis-options.c

/**
* add a option
*
* GOptionEntry
*/
int chassis_option_set(chassis_option_t *opt,
const char *long_name,
gchar short_name,
gint flags,
GOptionArg arg,
gpointer arg_data,
const char *description,
const char *arg_description,
chas_opt_assign_hook assign_hook,
chas_opt_show_hook show_hook,
gint opt_property) {
opt->long_name = g_strdup(long_name);
opt->short_name = short_name;
opt->flags = flags;
opt->arg = arg;
opt->arg_data = arg_data;
opt->description = g_strdup(description);
opt->arg_description = g_strdup(arg_description);
opt->assign_opts_hook = assign_hook;
opt->show_hook = show_hook;
opt->opt_property = opt_property; return ;
}

chassis_options_add_option
位置:src\chassis-options.c

/**
* add a option
*
* GOptionEntry
*/
int chassis_options_add_option(chassis_options_t *opts,
chassis_option_t *opt) { opts->options = g_list_append(opts->options, opt); return ;
}

chassis_options_to_g_option_entries
位置:src\chassis-options.c

/**
* convert the chassis_options into a GOptionEntry
*
* @see chassis_options_free_g_option_entries
*/
GOptionEntry *chassis_options_to_g_option_entries(chassis_options_t *opts) {
GOptionEntry *entries;
int count;
GList *node; /* build the GOptionEntry block */
for (node = opts->options, count = ; node; node = node->next) {
count++;
} entries = g_new0(GOptionEntry, count + );
for (node = opts->options, count = ; node; node = node->next) {
chassis_option_t *opt = node->data; entries[count].long_name = g_strdup(opt->long_name);
entries[count].short_name = opt->short_name;
entries[count].flags = opt->flags;
entries[count].arg = opt->arg;
entries[count].arg_data = opt->arg_data;
entries[count].description = g_strdup(opt->description);
entries[count].arg_description = g_strdup(opt->arg_description);
count++;
} entries[count].long_name = NULL;
entries[count].short_name = ;
entries[count].flags = ;
entries[count].arg = ;
entries[count].arg_data = NULL;
entries[count].description = NULL;
entries[count].arg_description = NULL; return entries;
}

chassis_keyfile_to_options
位置:src\chassis-keyfile.c

int chassis_keyfile_to_options(GKeyFile* keyfile, const gchar *ini_group_name, GOptionEntry *config_entries) {
GError *gerr = NULL;
int ret = ;
int i, j; /* all the options are in the group for "mysql-proxy" */ if (!keyfile) return -;
if (!g_key_file_has_group(keyfile, ini_group_name)) return ; /* set the defaults */
for (i = ; config_entries[i].long_name; i++) {
GOptionEntry *entry = &(config_entries[i]);
gchar *arg_string;
gchar **arg_string_array;
gboolean arg_bool = ;
gint arg_int = ;
gdouble arg_double = ;
gsize len = ; switch (entry->arg) {
case G_OPTION_ARG_FILENAME:
case G_OPTION_ARG_STRING:
/* is this option set already */
if (NULL == entry->arg_data || NULL != *(gchar **)(entry->arg_data)) break; arg_string = g_key_file_get_string(keyfile, ini_group_name, entry->long_name, &gerr);
if (!gerr) {
/* strip trailing spaces */
*(gchar **)(entry->arg_data) = g_strchomp(arg_string);
}
break;
case G_OPTION_ARG_FILENAME_ARRAY:
case G_OPTION_ARG_STRING_ARRAY:
/* is this option set already */
if (NULL == entry->arg_data || NULL != *(gchar ***)(entry->arg_data)) break; arg_string_array = g_key_file_get_string_list(keyfile, ini_group_name, entry->long_name, &len, &gerr);
if (!gerr) {
for (j = ; arg_string_array[j]; j++) {
arg_string_array[j] = g_strstrip(arg_string_array[j]);
}
*(gchar ***)(entry->arg_data) = arg_string_array;
}
break;
case G_OPTION_ARG_NONE:
arg_bool = g_key_file_get_boolean(keyfile, ini_group_name, entry->long_name, &gerr);
if (!gerr) {
*(int *)(entry->arg_data) = arg_bool;
}
break;
case G_OPTION_ARG_INT:
arg_int = g_key_file_get_integer(keyfile, ini_group_name, entry->long_name, &gerr);
if (!gerr) {
*(gint *)(entry->arg_data) = arg_int;
}
break;
#if GLIB_MAJOR_VERSION >= 2 && GLIB_MINOR_VERSION >= 12
case G_OPTION_ARG_DOUBLE:
arg_double = g_key_file_get_double(keyfile, ini_group_name, entry->long_name, &gerr);
if (!gerr) {
*(gdouble *)(entry->arg_data) = arg_double;
}
break;
#endif
default:
g_log_dbproxy(g_error, "(keyfile) the option %d can't be handled", entry->arg);
break;
} if (gerr) {
if (gerr->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND) {
g_log_dbproxy(g_critical, "%s", gerr->message);
ret = -;
} g_error_free(gerr);
gerr = NULL;
}
} return ret;
}

chassis_frontend_init_base_options
位置:src\chassis-frontend.c

int chassis_frontend_init_base_options(GOptionContext *option_ctx,
int *argc_p, char ***argv_p,
int *print_version,
char **config_file,
GError **gerr) {
chassis_options_t *opts;
GOptionEntry *base_main_entries;
int ret = ; opts = chassis_options_new();
chassis_options_set_cmdline_only_options(opts, print_version, config_file);
base_main_entries = chassis_options_to_g_option_entries(opts); g_option_context_add_main_entries(option_ctx, base_main_entries, NULL);
g_option_context_set_help_enabled(option_ctx, FALSE);
g_option_context_set_ignore_unknown_options(option_ctx, TRUE); if (FALSE == g_option_context_parse(option_ctx, argc_p, argv_p, gerr)) {
ret = -;
} /* do not use chassis_options_free_g_options... here, we need to hang on to the data until the end of the program! */
chassis_frontend_options_free(base_main_entries); chassis_options_free(opts); return ret;
}

chassis_options_set_cmdline_only_options
位置: src\chassis-frontend.c

/**
* setup the options that can only appear on the command-line
*/
int chassis_options_set_cmdline_only_options(chassis_options_t *opts,
int *print_version,
char **config_file) { chassis_options_add(opts,
"version", 'V', , G_OPTION_ARG_NONE, print_version, "Show version", NULL, NULL, NULL, ); chassis_options_add(opts,
"defaults-file", , , G_OPTION_ARG_STRING, config_file, "configuration file", "<file>", NULL, NULL, ); return ;
}

chassis_frontend_init_plugins
位置:src\chassis-frontend.c

int chassis_frontend_init_plugins(GPtrArray *plugins,
GOptionContext *option_ctx,
int *argc_p, char ***argv_p,
GKeyFile *keyfile,
const char* keyfile_section_name,
const char *base_dir,
GError **gerr) {
guint i; for (i = ; i < plugins->len; i++) {
GOptionEntry *config_entries = NULL;
chassis_plugin *p = plugins->pdata[i];
chassis_options_t *plugin_opts = NULL; if (NULL != (plugin_opts = chassis_plugin_get_options(p))) {
gchar *group_desc = g_strdup_printf("%s-module", p->option_grp_name);
gchar *help_msg = g_strdup_printf("Show options for the %s-module", p->option_grp_name);
const gchar *group_name = p->option_grp_name; config_entries = chassis_options_to_g_option_entries(plugin_opts); GOptionGroup *option_grp = g_option_group_new(group_name, group_desc, help_msg, NULL, NULL);
g_option_group_add_entries(option_grp, config_entries);
g_option_context_add_group(option_ctx, option_grp); g_free(help_msg);
g_free(group_desc); /* parse the new options */
if (FALSE == g_option_context_parse(option_ctx, argc_p, argv_p, gerr)) {
return -;
} if (keyfile) {
if (chassis_keyfile_to_options(keyfile, keyfile_section_name, config_entries)) {
return -;
}
} /* resolve the path names for these config entries */
chassis_keyfile_resolve_path(base_dir, config_entries);
} if (config_entries != NULL) {
chassis_frontend_options_free(config_entries);
}
} return ;
}

chassis_plugin_get_options
位置:src\chassis-plugin.c

chassis_options_t* chassis_plugin_get_options(chassis_plugin *p) {
chassis_options_t * options; if (!p->get_options) return NULL; if (NULL == (options = p->get_options(p->config))) {
g_log_dbproxy(g_critical, "adding config options for module '%s' failed", p->name);
} return options;
}

chassis_frontend_load_plugins
位置src\chassis-frontend.c

int chassis_frontend_load_plugins(GPtrArray *plugins, const gchar *plugin_dir, gchar **plugin_names) {
int i; /* load the plugins */
for (i = ; plugin_names && plugin_names[i]; i++) {
chassis_plugin *p; char *plugin_filename;
/* skip trying to load a plugin when the parameter was --plugins=
that will never work...
*/
if (!g_strcmp0("", plugin_names[i])) {
continue;
} plugin_filename = g_strdup_printf("%s%c%s%s.%s",
plugin_dir,
G_DIR_SEPARATOR,
G_MODULE_PREFIX,
plugin_names[i],
SHARED_LIBRARY_SUFFIX); p = chassis_plugin_load(plugin_filename);
g_free(plugin_filename); if (NULL == p) {
g_log_dbproxy(g_critical, "setting --plugin-dir=<dir> might help");
return -;
}
p->option_grp_name = g_strdup(plugin_names[i]); g_ptr_array_add(plugins, p);
}
return ;
}

chassis_plugin_load
位置:src\chassis-plugin.c

chassis_plugin* chassis_plugin_load(const gchar *name) {
int (*plugin_init)(chassis_plugin *p);
chassis_plugin *p = chassis_plugin_new(); p->module = g_module_open(name, G_MODULE_BIND_LOCAL); if (!p->module) {
g_log_dbproxy(g_critical, "loading module '%s' failed: %s", name, g_module_error()); chassis_plugin_free(p); return NULL;
} /* each module has to have a plugin_init function */
if (!g_module_symbol(p->module, "plugin_init", (gpointer) &plugin_init)) {
g_log_dbproxy(g_critical, "module '%s' doesn't have a init-function: %s", name, g_module_error());
chassis_plugin_free(p);
return NULL;
} if ( != plugin_init(p)) {
g_log_dbproxy(g_critical, "init-function for module '%s' failed", name);
chassis_plugin_free(p);
return NULL;
} if (p->magic != CHASSIS_PLUGIN_MAGIC) {
g_log_dbproxy(g_critical, "plugin '%s' doesn't match the current plugin interface (plugin is %lx, chassis is %lx)", name, p->magic, CHASSIS_PLUGIN_MAGIC);
chassis_plugin_free(p);
return NULL;
} if (p->init) {
p->config = p->init();
} /* if the plugins haven't set p->name provide our own name */
if (!p->name) p->name = g_strdup(name);
/* set dummy version number if the plugin doesn't provide a real one */
if (!p->version) {
g_log_dbproxy(g_critical, "plugin '%s' doesn't set a version number, refusing to load this plugin", name);
chassis_plugin_free(p);
return NULL;
} if (p->new_stats) {
p->stats = p->new_stats();
} return p;
}

plugin_init
位置:plugins\proxy\proxy-plugin.c

G_MODULE_EXPORT int plugin_init(chassis_plugin *p) {
p->magic = CHASSIS_PLUGIN_MAGIC;
p->name = g_strdup("proxy");
p->version = g_strdup(PACKAGE_VERSION); p->init = network_mysqld_proxy_plugin_new;
p->get_options = network_mysqld_proxy_plugin_get_options;
p->apply_config = network_mysqld_proxy_plugin_apply_config;
p->destroy = network_mysqld_proxy_plugin_free; return ;
}

network_mysqld_proxy_plugin_new
位置:plugins\proxy\proxy-plugin.c

//全局变量
chassis_plugin_config *config = NULL; chassis_plugin_config * network_mysqld_proxy_plugin_new(void) {
config = g_new0(chassis_plugin_config, ); config->fix_bug_25371 = ; /** double ERR packet on AUTH failures */
config->profiling = ;
config->start_proxy = ;
config->pool_change_user = ; /* issue a COM_CHANGE_USER to cleanup the connection
when we get back the connection from the pool */
config->dt_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)dt_table_free); config->select_where_limit_str = NULL;
config->select_where_limit = SEL_OFF;
config->charset = NULL; config->opts = NULL; config->percentile_value = ; config->check_state_conn_timeout = ;
config->check_state_interval = PROXY_CHECK_STATE_WAIT_TIMEOUT;
config->check_state_retry_times = RETRY_TIMES;
config->check_state_sleep_delay = SLEEP_DELAY;
g_rw_lock_init(&config->config_lock); config->sql_log_mgr = sql_log_t_new();
config->percentile_controller = pt_percentile_new(6.0, 29.0, ); config->plugin_threads = g_hash_table_new_full(g_str_hash,
g_str_equal,
g_free,
(GDestroyNotify)plugin_thread_t_free);
config->table_prefix = NULL;
config->table_suffix = NULL;
config->tnw = tbl_name_wrap_new(); return config;
}

network_mysqld_proxy_plugin_get_options
位置:plugins\proxy\proxy-plugin.c

设置插件的选项
我们更改的id-generate 就在这里
需要在 )config增加新的属性id-generate
./plugins/proxy/proxy-plugin.h
struct chassis_plugin_config {
...
gchar* id_generate;
};
)初始化
./plugins/proxy/proxy-plugin.c
chassis_plugin_config * network_mysqld_proxy_plugin_new(void) {
...
config->id_generate = NULL;
return config;
}
static chassis_options_t * network_mysqld_proxy_plugin_get_options(chassis_plugin_config *oldconfig) {
if (config->opts == NULL) {
chassis_options_t *opts = chassis_options_new(); chassis_options_add(opts, "proxy-address", 'P', , G_OPTION_ARG_STRING, &(config->address), "listening address:port of the proxy-server (default: :4040)", "<host:port>",
NULL, show_proxy_address, SHOW_OPTS_PROPERTY);
chassis_options_add(opts, "id-generate", , , G_OPTION_ARG_STRING, &(config->id_generate), "Run mysql-proxy as user", NULL, NULL, NULL, ); config->opts = opts;
} return config->opts;
}

chassis_mainloop
位置:src\chassis-mainloop.c

int chassis_mainloop(void *_chas) {
chassis *chas = _chas;
guint i;
struct event ev_sigterm, ev_sigint;
#ifdef SIGHUP
struct event ev_sighup;
#endif
chassis_event_thread_t *mainloop_thread; /* redirect logging from libevent to glib */
event_set_log_callback(event_log_use_glib); /* add a event-handler for the "main" events */
mainloop_thread = chassis_event_thread_new();
chassis_event_threads_init_thread(mainloop_thread, chas);
g_ptr_array_add(chas->threads, mainloop_thread); chas->event_base = mainloop_thread->event_base; /* all global events go to the 1st thread */ g_assert(chas->event_base); /* setup all plugins all plugins */
for (i = ; i < chas->modules->len; i++) {
chassis_plugin *p = chas->modules->pdata[i]; g_assert(p->apply_config);
if ( != p->apply_config(chas, p->config)) {
g_log_dbproxy(g_critical, "applying config of plugin %s failed", p->name);
return -;
}
} signal_set(&ev_sigterm, SIGTERM, sigterm_handler, NULL);
event_base_set(chas->event_base, &ev_sigterm);
signal_add(&ev_sigterm, NULL); signal_set(&ev_sigint, SIGINT, sigint_handler, NULL);
event_base_set(chas->event_base, &ev_sigint);
signal_add(&ev_sigint, NULL); #ifdef SIGHUP
signal_set(&ev_sighup, SIGHUP, sighup_handler, chas);
event_base_set(chas->event_base, &ev_sighup);
if (signal_add(&ev_sighup, NULL)) {
g_log_dbproxy(g_critical, "signal_add(SIGHUP) failed");
}
#endif if (chas->event_thread_count < ) chas->event_thread_count = ; /* create the event-threads
*
* - dup the async-queue-ping-fds
* - setup the events notification
* */
for (i = ; i <= (guint)chas->event_thread_count; i++) { /* we already have 1 event-thread running, the main-thread */
chassis_event_thread_t *thread = chassis_event_thread_new(i); chassis_event_threads_init_thread(thread, chas); g_ptr_array_add(chas->threads, thread);
} /* start the event threads */
chassis_event_threads_start(chas->threads); /**
* handle signals and all basic events into the main-thread
*
* block until we are asked to shutdown
*/
chassis_mainloop_thread_loop(mainloop_thread); signal_del(&ev_sigterm);
signal_del(&ev_sigint);
#ifdef SIGHUP
signal_del(&ev_sighup);
#endif
return ;
}

chassis_event_thread_new
位置:src\chassis-event-thread.c

/**
* create the data structure for a new event-thread
*/
chassis_event_thread_t* chassis_event_thread_new(guint index) {
chassis_event_thread_t *thread = g_new0(chassis_event_thread_t, ); thread->index = index; thread->event_queue = g_async_queue_new(); g_rw_lock_init(&thread->connection_lock);
thread->connection_list = NULL; thread->exit_phase = EVENT_THREAD_NORMAL;
return thread;
}

chassis_event_threads_init_thread
位置:src\chassis-event-thread.c

/**
* setup the notification-fd of a event-thread
*
* all event-threads listen on the same notification pipe
*
* @see chassis_event_handle()
*/
int chassis_event_threads_init_thread(chassis_event_thread_t *thread, chassis *chas) {
thread->event_base = event_base_new();
thread->chas = chas; int fds[];
if (pipe(fds)) {
int err;
err = errno;
g_log_dbproxy(g_error, "evutil_socketpair() failed: %s (%d)", g_strerror(err), err);
}
thread->notify_receive_fd = fds[];
thread->notify_send_fd = fds[]; event_set(&(thread->notify_fd_event), thread->notify_receive_fd, EV_READ | EV_PERSIST, chassis_event_handle, thread);
event_base_set(thread->event_base, &(thread->notify_fd_event));
event_add(&(thread->notify_fd_event), NULL); return ;
}

chassis_event_threads_start
位置:src\chassis-event-thread.c

/**
* start all the event-threads
*
* starts all the event-threads that got added by chassis_event_threads_add()
*
* @see chassis_event_threads_add
*/
void chassis_event_threads_start(GPtrArray *threads) {
guint i; g_log_dbproxy(g_message, "starting %d threads", threads->len - ); for (i = ; i < threads->len; i++) { /* the 1st is the main-thread and already set up */
chassis_event_thread_t *thread = threads->pdata[i];
GError *gerr = NULL; thread->thr = g_thread_try_new("event thread", (GThreadFunc)chassis_event_thread_loop, thread, &gerr);
if (gerr) {
g_log_dbproxy(g_critical, "%s", gerr->message);
g_error_free(gerr);
gerr = NULL;
}
}
}

chassis_mainloop_thread_loop
位置:src\chassis-event-thread.c

/**
* event-handler thread
*
*/
void* chassis_mainloop_thread_loop(chassis_event_thread_t *thread) {
cur_thid = thread->index;
gboolean is_all_work_thread_exit = FALSE;
g_assert(thread->index == ); /**
* check once a second if we shall shutdown the proxy
*/
while (!chassis_is_shutdown() || !is_all_work_thread_exit) {
struct timeval timeout;
int r; timeout.tv_sec = ;
timeout.tv_usec = ; g_assert(event_base_loopexit(thread->event_base, &timeout) == ); r = event_base_dispatch(thread->event_base); if (r == -) {
if (errno == EINTR) continue;
g_log_dbproxy(g_critical, "leaving chassis_event_thread_loop early, errno != EINTR was: %s (%d)", g_strerror(errno), errno);
break;
} if (chassis_is_shutdown()) {
gint i = ;
for (; i < thread->chas->threads->len; i++) {
chassis_event_thread_t *event_thread = g_ptr_array_index(thread->chas->threads, i);
if (g_atomic_int_get(&event_thread->exit_phase) != EVENT_THREAD_EXITED) break;
}
if (i == thread->chas->threads->len) {
is_all_work_thread_exit = TRUE;
}
}
} g_log_dbproxy(g_message, "main loop thread will exit"); return NULL;
}

dbproxy-main函数的更多相关文章

  1. [C#] 了解过入口函数 Main() 吗?带你用批处理玩转 Main 函数

    了解过入口函数 Main() 吗?带你用批处理玩转 Main 函数 目录 简介 特点 方法的参数 方法的返回值 与批处理交互的一个示例 简介 我们知道,新建一个控制台应用程序的时候,IDE 会同时创建 ...

  2. 选择目录,选择文件夹的COM组件问题。在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式。请确保您的 Main 函数带有 STAThreadAttribute 标记。 只有将调试器附加到该进程才会引发此异常。

    异常: 在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式.请确保您的 Main 函数带有 STAThreadAttribute 标记. 只有将调试器附加到该进程才会引发此异常. ...

  3. eclipse的maven项目,如何使用java run main函数

    项目使用maven管理,一般说来就使用jetty:run了.但是对于做功能测试和集成测试的用例,需要使用自定义的quickrun来运行进行测试环境的参数设定和功能隔离,google一番发现maven有 ...

  4. [汇编与C语言关系]2. main函数与启动例程

    为什么汇编程序的入口是_start,而C程序的入口是main函数呢?以下就来解释这个问题 在<x86汇编程序基础(AT&T语法)>一文中我们汇编和链接的步骤是: $ as hell ...

  5. 【Go入门教程3】流程(if、goto、for、switch)和函数(多个返回值、变参、传值与传指针、defer、函数作为值/类型、Panic和Recover、main函数和init函数、import)

    这小节我们要介绍Go里面的流程控制以及函数操作. 流程控制 流程控制在编程语言中是最伟大的发明了,因为有了它,你可以通过很简单的流程描述来表达很复杂的逻辑.Go中流程控制分三大类:条件判断,循环控制和 ...

  6. linux c 笔记-2 Hello World & main函数

    按照惯例撸一个hello_world.c #include <stdio.h> int main(int argc, char * argv[]) { printf("hello ...

  7. Spark&Hadoop:scala编写spark任务jar包,运行无法识别main函数,怎么办?

    昨晚和同事一起看一个scala写的程序,程序都写完了,且在idea上debug运行是ok的.但我们不能调试的方式部署在客户机器上,于是打包吧.打包时,我们是采用把外部引入的五个包(spark-asse ...

  8. [ASM C/C++] C语言的main 函数

    C语言有两种可能的运行环境 1. 独立(freestanding) 在独立环境中,C程序执行不需要操作系统的支持,因此只具有最小的链接库能力. 2. 宿主(hosted) 在宿主的环境中,C程序会在操 ...

  9. main函数的详解

    public : 公共的. 权限是最大,在任何情况下都可以访问. 原因: 为了保证让jvm在任何情况下都可以访问到main方法. static: 静态.静态可以让jvm调用main函数的时候更加的方便 ...

  10. Linux中Main函数的执行过程

    1. 问题:Linux如何执行main函数. 本文使用一个简单的C程序(simple.c)作为例子讲解.代码如下, int main() { return(0); } 2.  编译 -#gcc -o ...

随机推荐

  1. c# 遍历一个对象里面的全部属性

    比如我现在有一个Student的对象,里面有属性stuName,stuAge,stuGender,我现在该怎么写循环才能遍历这几个属性? Student s=new...... foreach (Sy ...

  2. Computer2

    luo@luo-All-Series:~/MyFile/TensorflowProject$ conda create -n flappbird1 python=3.7Solving environm ...

  3. catkin_make与gtest出现冲突的问题与解决

    gtest是测试时调用的,把测试禁止掉试试 catkin_make --pkg pkgname -DCATKIN_ENABLE_TESTING=0

  4. [SoapUI] SOAP UI-Groovy Useful Commands

    Hi All, I have posted the SOAPUI and Groovy useful commands that may help you in your testing. Below ...

  5. mysql中查看表结构的sql语句

    mysql查看表结构命令,如下: desc 表名;show columns from 表名;describe 表名;show create table 表名; use information_sche ...

  6. 遍历properties文件

    Properties pro = new Properties();try {    InputStream inStr = ClassLoader.getSystemResourceAsStream ...

  7. css实现二级菜单显示和收缩

    <ul class="nav"> <li><a href="#">一级菜单</a> <ul class=& ...

  8. 设计模式20:Memento 备忘录模式(行为型模式)

    Memento 备忘录模式(行为型模式) 对象状态的回溯 对象状态的变化无端,如何回溯.恢复对象在某个点的状态? 动机(Motivation) 在软件构建过程中,某些对象的状态在转换过程中,可能由于某 ...

  9. Android测试入门篇

    Android本身是一套软件堆叠(Software Stack),或者成为软件叠层架构,叠层主要分成三层:操作系统.中间件和应用程序. Android构架 1. Application 应用程序层:用 ...

  10. C#中的异步调用及异步设计模式(一)

    近期项目中使用了不少异步操作,关于“异步”做个总结.总结的内容大部分都来自于MSDN,还有一些自己的心得. 关于“异步”的使用可分为:使用层面和类库设计层面,细分如下: 一.使用异步方式调用同步方法( ...