mirror of
https://gitee.com/acl-dev/acl.git
synced 2024-11-30 02:47:56 +08:00
Optimize and test sharing stack of fiber.
This commit is contained in:
parent
39c749a13d
commit
5de8370700
@ -36,6 +36,9 @@ typedef struct THREAD {
|
||||
int nlocal;
|
||||
|
||||
#ifdef SHARE_STACK
|
||||
# ifdef USE_VALGRIND
|
||||
unsigned int vid;
|
||||
# endif
|
||||
char *stack_buff;
|
||||
size_t stack_size;
|
||||
size_t stack_dlen;
|
||||
@ -89,6 +92,9 @@ static void thread_free(void *ctx)
|
||||
}
|
||||
|
||||
#ifdef SHARE_STACK
|
||||
# ifdef USE_VALGRIND
|
||||
VALGRIND_STACK_DEREGISTER(tf->vid);
|
||||
# endif
|
||||
mem_free(tf->stack_buff);
|
||||
#endif
|
||||
|
||||
@ -159,6 +165,10 @@ static void fiber_check(void)
|
||||
#ifdef SHARE_STACK
|
||||
__thread_fiber->stack_size = __shared_stack_size;
|
||||
__thread_fiber->stack_buff = mem_malloc(__thread_fiber->stack_size);
|
||||
# ifdef USE_VALGRIND
|
||||
__thread_fiber->vid = VALGRIND_STACK_REGISTER(__thread_fiber->stack_buff,
|
||||
__thread_fiber->stack_buff + __shared_stack_size);
|
||||
# endif
|
||||
__thread_fiber->stack_dlen = 0;
|
||||
#endif
|
||||
|
||||
|
@ -267,9 +267,10 @@ public:
|
||||
* @param fn {void (*)(ACL_FIBER*, void*)} 协程函数执行入口
|
||||
* @param ctx {void*} 传递给协程执行函数的参数
|
||||
* @param size {size_t} 协程栈大小
|
||||
* @param share_stack {bool} 是否创建共享栈协程
|
||||
*/
|
||||
static void fiber_create(void (*fn)(ACL_FIBER*, void*),
|
||||
void* ctx, size_t size);
|
||||
void* ctx, size_t size, bool share_stack = false);
|
||||
|
||||
/**
|
||||
* 获得指定协程的堆栈
|
||||
|
@ -22,7 +22,8 @@ public:
|
||||
};
|
||||
|
||||
#define go acl::go_fiber()>
|
||||
#define go_stack(size) acl::go_fiber(size)>
|
||||
#define go_stack(size) acl::go_fiber(size, false)>
|
||||
#define go_share(size) acl::go_fiber(size, true)>
|
||||
|
||||
#define go_wait_fiber acl::go_fiber()<
|
||||
#define go_wait_thread acl::go_fiber()<<
|
||||
@ -32,12 +33,12 @@ class go_fiber
|
||||
{
|
||||
public:
|
||||
go_fiber(void) {}
|
||||
go_fiber(size_t stack_size) : stack_size_(stack_size) {}
|
||||
go_fiber(size_t stack_size, bool on) : stack_size_(stack_size), stack_share_(on) {}
|
||||
|
||||
void operator > (std::function<void()> fn)
|
||||
{
|
||||
fiber_ctx* ctx = new fiber_ctx(fn);
|
||||
fiber::fiber_create(fiber_main, (void*) ctx, stack_size_);
|
||||
fiber::fiber_create(fiber_main, (void*) ctx, stack_size_, stack_share_);
|
||||
}
|
||||
|
||||
void operator < (std::function<void()> fn)
|
||||
@ -65,7 +66,8 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
size_t stack_size_ = 320000;
|
||||
size_t stack_size_ = 320000;
|
||||
bool stack_share_ = false;
|
||||
|
||||
static void fiber_main(ACL_FIBER*, void* ctx)
|
||||
{
|
||||
|
@ -177,6 +177,7 @@ void fiber::start(size_t stack_size /* 64000 */, bool share_stack /* false */)
|
||||
acl_msg_fatal("%s(%d), %s: fiber-%u, already running!",
|
||||
__FILE__, __LINE__, __FUNCTION__, self());
|
||||
}
|
||||
|
||||
ACL_FIBER_ATTR attr;
|
||||
acl_fiber_attr_init(&attr);
|
||||
acl_fiber_attr_setstacksize(&attr, stack_size);
|
||||
@ -307,9 +308,15 @@ void fiber::stdout_open(bool on)
|
||||
acl_fiber_msg_stdout_enable(on ? 1 : 0);
|
||||
}
|
||||
|
||||
void fiber::fiber_create(void (*fn)(ACL_FIBER*, void*), void* ctx, size_t size)
|
||||
void fiber::fiber_create(void (*fn)(ACL_FIBER*, void*), void* ctx,
|
||||
size_t stack_size, bool share_stack /* false */)
|
||||
{
|
||||
acl_fiber_create(fn, (void*) ctx, size);
|
||||
ACL_FIBER_ATTR attr;
|
||||
acl_fiber_attr_init(&attr);
|
||||
acl_fiber_attr_setstacksize(&attr, stack_size);
|
||||
acl_fiber_attr_setsharestack(&attr, share_stack ? 1 : 0);
|
||||
|
||||
acl_fiber_create2(&attr, fn, ctx);
|
||||
}
|
||||
|
||||
void fiber::stacktrace(const fiber& fb, std::vector<fiber_frame>& out, size_t max)
|
||||
|
0
lib_fiber/samples/chat/client/valgrind.sh
Normal file → Executable file
0
lib_fiber/samples/chat/client/valgrind.sh
Normal file → Executable file
@ -16,18 +16,16 @@ static std::map<acl::string, user_client*> __users;
|
||||
static void remove_user(user_client* uc)
|
||||
{
|
||||
const char* name = uc->get_name();
|
||||
if (name == NULL || *name == 0)
|
||||
{
|
||||
if (name == NULL || *name == 0) {
|
||||
printf("%s(%d): no name!\r\n", __FUNCTION__, __LINE__);
|
||||
return;
|
||||
}
|
||||
|
||||
std::map<acl::string, user_client*>::iterator it = __users.find(name);
|
||||
if (it == __users.end())
|
||||
if (it == __users.end()) {
|
||||
printf("%s(%d): not exist, name: %s\r\n",
|
||||
__FUNCTION__, __LINE__, name);
|
||||
else
|
||||
{
|
||||
} else {
|
||||
__users.erase(it);
|
||||
printf("delete user ok, name: %s\r\n", name);
|
||||
}
|
||||
@ -37,20 +35,19 @@ static void remove_user(user_client* uc)
|
||||
static void client_logout(user_client* client)
|
||||
{
|
||||
// 从客户端列表中删除
|
||||
if (client->already_login())
|
||||
if (client->already_login()) {
|
||||
remove_user(client);
|
||||
}
|
||||
|
||||
// 如果该客户端的读协程还在工作,则通知该读协程退出
|
||||
if (client->is_reading())
|
||||
{
|
||||
if (client->is_reading()) {
|
||||
printf("%s(%d): user: %s, kill_reader\r\n",
|
||||
__FUNCTION__, __LINE__, client->get_name());
|
||||
client->kill_reader();
|
||||
}
|
||||
|
||||
// 如果该客户端的写协程还在工作,则通知该写协程退出
|
||||
if (client->is_waiting())
|
||||
{
|
||||
if (client->is_waiting()) {
|
||||
printf("fiber-%d: %s(%d): user: %s, notify logout\r\n",
|
||||
acl_fiber_self(), __FUNCTION__, __LINE__,
|
||||
client->get_name());
|
||||
@ -58,8 +55,9 @@ static void client_logout(user_client* client)
|
||||
}
|
||||
|
||||
// 如果该客户端的读、写协程都已经退出,则通知该客户端退出
|
||||
if (!client->is_reading() && !client->is_waiting())
|
||||
if (!client->is_reading() && !client->is_waiting()) {
|
||||
client->notify_exit();
|
||||
}
|
||||
}
|
||||
|
||||
static bool client_flush(user_client* client)
|
||||
@ -70,10 +68,8 @@ static bool client_flush(user_client* client)
|
||||
bool ret = true;
|
||||
|
||||
// 从客户端的消息队列中提取消息并发送至该客户端
|
||||
while ((msg = client->pop()) != NULL)
|
||||
{
|
||||
if (conn.write(*msg) == -1)
|
||||
{
|
||||
while ((msg = client->pop()) != NULL) {
|
||||
if (conn.write(*msg) == -1) {
|
||||
printf("flush to user: %s error %s\r\n",
|
||||
client->get_name(), acl::last_serror());
|
||||
delete msg;
|
||||
@ -95,16 +91,14 @@ static void fiber_writer(user_client* client)
|
||||
client->set_waiter();
|
||||
client->set_waiting(true);
|
||||
|
||||
while (true)
|
||||
{
|
||||
while (true) {
|
||||
int mtype;
|
||||
|
||||
// 等待消息通知
|
||||
client->wait(mtype);
|
||||
|
||||
// 从本身消息队列中提取消息并发送至本客户端
|
||||
if (client_flush(client) == false)
|
||||
{
|
||||
if (client_flush(client) == false) {
|
||||
printf("%s(%d), user: %s, flush error %s\r\n",
|
||||
__FUNCTION__, __LINE__, client->get_name(),
|
||||
acl::last_serror());
|
||||
@ -112,22 +106,19 @@ static void fiber_writer(user_client* client)
|
||||
}
|
||||
|
||||
#ifdef USE_CHAN
|
||||
if (mtype == MT_LOGOUT)
|
||||
{
|
||||
if (mtype == MT_LOGOUT) {
|
||||
printf("%s(%d), user: %s, MT_LOGOUT\r\n",
|
||||
__FUNCTION__, __LINE__, client->get_name());
|
||||
break;
|
||||
}
|
||||
if (mtype == MT_KICK)
|
||||
{
|
||||
if (mtype == MT_KICK) {
|
||||
printf("%s(%d), user: %s, MT_KICK\r\n",
|
||||
__FUNCTION__, __LINE__, client->get_name());
|
||||
client->get_stream().write("You're kicked\r\n");
|
||||
break;
|
||||
}
|
||||
#else
|
||||
if (client->exiting())
|
||||
{
|
||||
if (client->exiting()) {
|
||||
printf("%s(%d), user: %s exiting\r\n",
|
||||
__FUNCTION__, __LINE__, client->get_name());
|
||||
break;
|
||||
@ -150,29 +141,26 @@ static bool client_login(user_client* uc)
|
||||
{
|
||||
acl::string buf;
|
||||
|
||||
while (true)
|
||||
{
|
||||
while (true) {
|
||||
// 读取一行数据,且自动去掉尾部的 \r\n
|
||||
if (uc->get_stream().gets(buf) == false)
|
||||
{
|
||||
if (uc->get_stream().gets(buf) == false) {
|
||||
printf("%s(%d): gets error %s\r\n",
|
||||
__FUNCTION__, __LINE__, acl::last_serror());
|
||||
|
||||
if (errno == FIBER_ETIME)
|
||||
{
|
||||
if (errno == FIBER_ETIME) {
|
||||
printf("Login timeout\r\n");
|
||||
uc->get_stream().write("Login timeout\r\n");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (!buf.empty())
|
||||
if (!buf.empty()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 分析登入消息,数据格式:login|xxx
|
||||
std::vector<acl::string>& tokens = buf.split2("|");
|
||||
if (tokens.size() < 2)
|
||||
{
|
||||
if (tokens.size() < 2) {
|
||||
acl::string tmp;
|
||||
tmp.format("invalid argc: %d < 2\r\n", (int) tokens.size());
|
||||
printf("%s", tmp.c_str());
|
||||
@ -185,14 +173,13 @@ static bool client_login(user_client* uc)
|
||||
// 当该客户端不存在时添加进客户端列表中
|
||||
const acl::string& name = tokens[1];
|
||||
std::map<acl::string, user_client*>::iterator it = __users.find(name);
|
||||
if (it == __users.end())
|
||||
{
|
||||
if (it == __users.end()) {
|
||||
__users[name] = uc;
|
||||
uc->set_name(name);
|
||||
msg.format("user %s login ok\r\n", name.c_str());
|
||||
}
|
||||
else
|
||||
} else {
|
||||
msg.format("user %s already login\r\n", name.c_str());
|
||||
}
|
||||
|
||||
printf("%s", msg.c_str());
|
||||
|
||||
@ -203,8 +190,7 @@ static bool client_login(user_client* uc)
|
||||
// 与其它客户端聊天过程
|
||||
static bool client_chat(user_client* uc, std::vector<acl::string>& tokens)
|
||||
{
|
||||
if (tokens.size() < 3)
|
||||
{
|
||||
if (tokens.size() < 3) {
|
||||
printf("invalid argc: %d < 3\r\n", (int) tokens.size());
|
||||
return true;
|
||||
}
|
||||
@ -214,8 +200,7 @@ static bool client_chat(user_client* uc, std::vector<acl::string>& tokens)
|
||||
|
||||
// 查找目标客户端对象
|
||||
std::map<acl::string, user_client*>::iterator it = __users.find(to);
|
||||
if (it == __users.end())
|
||||
{
|
||||
if (it == __users.end()) {
|
||||
acl::string tmp;
|
||||
tmp.format("chat >> from user: %s, to user: %s not exist\r\n",
|
||||
uc->get_name(), to.c_str());
|
||||
@ -234,8 +219,7 @@ static bool client_chat(user_client* uc, std::vector<acl::string>& tokens)
|
||||
// 踢出一个客户端对象
|
||||
static bool client_kick(user_client* uc, std::vector<acl::string>& tokens)
|
||||
{
|
||||
if (tokens.size() < 2)
|
||||
{
|
||||
if (tokens.size() < 2) {
|
||||
printf("invalid argc: %d < 2\r\n", (int) tokens.size());
|
||||
return true;
|
||||
}
|
||||
@ -244,8 +228,7 @@ static bool client_kick(user_client* uc, std::vector<acl::string>& tokens)
|
||||
|
||||
// 查找将被踢出的客户端对象
|
||||
std::map<acl::string, user_client*>::iterator it = __users.find(to);
|
||||
if (it == __users.end())
|
||||
{
|
||||
if (it == __users.end()) {
|
||||
acl::string tmp;
|
||||
tmp.format("kick >> from user: %s, to user: %s not exist\r\n",
|
||||
uc->get_name(), to.c_str());
|
||||
@ -271,8 +254,7 @@ static void fiber_reader(user_client* client)
|
||||
client->set_reading(true);
|
||||
|
||||
// 登入服务器
|
||||
if (client_login(client) == false)
|
||||
{
|
||||
if (client_login(client) == false) {
|
||||
client->set_reading(false);
|
||||
printf("----------client_logout-------\r\n");
|
||||
|
||||
@ -284,7 +266,7 @@ static void fiber_reader(user_client* client)
|
||||
}
|
||||
|
||||
// 登入成功,则创建写协程用来向客户端发送消息
|
||||
go_stack(STACK_SIZE) [&] {
|
||||
go_share(STACK_SIZE) [&] {
|
||||
__nwriter++;
|
||||
fiber_writer(client);
|
||||
};
|
||||
@ -295,33 +277,27 @@ static void fiber_reader(user_client* client)
|
||||
acl::string buf;
|
||||
|
||||
// 从客户端循环读取消息
|
||||
while (true)
|
||||
{
|
||||
while (true) {
|
||||
bool ret = conn.gets(buf);
|
||||
if (ret == false)
|
||||
{
|
||||
if (ret == false) {
|
||||
printf("%s(%d): user: %s, gets error %s, fiber: %d\r\n",
|
||||
__FUNCTION__, __LINE__, client->get_name(),
|
||||
acl::last_serror(), acl_fiber_self());
|
||||
|
||||
// 客户端退出
|
||||
if (client->exiting())
|
||||
{
|
||||
if (client->exiting()) {
|
||||
printf("----exiting now----\r\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (errno == FIBER_ETIME)
|
||||
{
|
||||
if (conn.write("ping\r\n") == -1)
|
||||
{
|
||||
if (errno == FIBER_ETIME) {
|
||||
if (conn.write("ping\r\n") == -1) {
|
||||
printf("ping error\r\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (errno == EAGAIN)
|
||||
} else if (errno == EAGAIN) {
|
||||
printf("EAGAIN\r\n");
|
||||
else {
|
||||
} else {
|
||||
printf("gets error: %d, %s\r\n",
|
||||
errno, acl::last_serror());
|
||||
break;
|
||||
@ -330,42 +306,41 @@ static void fiber_reader(user_client* client)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (buf.empty())
|
||||
if (buf.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 分析客户端发送的消息,交由不同的处理过程
|
||||
std::vector<acl::string>& tokens = buf.split2("|");
|
||||
|
||||
// 本客户端要求退出
|
||||
if (tokens[0] == "quit" || tokens[0] == "exit")
|
||||
{
|
||||
if (tokens[0] == "quit" || tokens[0] == "exit") {
|
||||
conn.write("Bye!\r\n");
|
||||
break;
|
||||
}
|
||||
|
||||
// 本客户端发送聊天消息
|
||||
else if (tokens[0] == "chat")
|
||||
{
|
||||
if (client_chat(client, tokens) == false)
|
||||
else if (tokens[0] == "chat") {
|
||||
if (client_chat(client, tokens) == false) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 本客户端踢出其它客户端
|
||||
else if (tokens[0] == "kick")
|
||||
{
|
||||
if (client_kick(client, tokens) == false)
|
||||
else if (tokens[0] == "kick") {
|
||||
if (client_kick(client, tokens) == false) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 要求整个服务进程退出
|
||||
else if (tokens[0] == "stop")
|
||||
{
|
||||
else if (tokens[0] == "stop") {
|
||||
stop = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
} else {
|
||||
printf("invalid data: %s, cmd: [%s]\r\n",
|
||||
buf.c_str(), tokens[0].c_str());
|
||||
}
|
||||
}
|
||||
|
||||
printf(">>%s(%d), user: %s, logout\r\n", __FUNCTION__, __LINE__,
|
||||
@ -378,8 +353,7 @@ static void fiber_reader(user_client* client)
|
||||
|
||||
printf("----__nreader: %d-----\r\n", --__nreader);
|
||||
|
||||
if (stop)
|
||||
{
|
||||
if (stop) {
|
||||
int dumy = 1;
|
||||
// 如果要停止服务,则通知监控协程
|
||||
__chan_monitor.put(dumy);
|
||||
@ -394,7 +368,7 @@ static void fiber_client(acl::socket_stream* conn)
|
||||
user_client* client = new user_client(*conn);
|
||||
|
||||
// 创建从客户端连接读取数据的协程
|
||||
go_stack(STACK_SIZE) [=] {
|
||||
go_share(STACK_SIZE) [=] {
|
||||
__nreader++;
|
||||
fiber_reader(client);
|
||||
};
|
||||
@ -418,18 +392,16 @@ static void fiber_accept(acl::server_socket& ss)
|
||||
{
|
||||
__fiber_accept = acl_fiber_running();
|
||||
|
||||
while (true)
|
||||
{
|
||||
while (true) {
|
||||
// 等待接收客户端连接
|
||||
acl::socket_stream* conn = ss.accept();
|
||||
if (conn == NULL)
|
||||
{
|
||||
if (conn == NULL) {
|
||||
printf("accept error %s\r\n", acl::last_serror());
|
||||
break;
|
||||
}
|
||||
|
||||
// 创建处理客户端对象的协程
|
||||
go_stack(STACK_SIZE) [=] {
|
||||
go_share(STACK_SIZE) [=] {
|
||||
__nclients++;
|
||||
fiber_client(conn);
|
||||
};
|
||||
@ -455,7 +427,7 @@ static void fiber_monitor(void)
|
||||
static void usage(const char *procname)
|
||||
{
|
||||
printf("usage: %s -h [help]\r\n"
|
||||
" -s listen_addr\r\n"
|
||||
" -s listen_addr[default: 127.0.0.1:9002]\r\n"
|
||||
" -r rw_timeout\r\n" , procname);
|
||||
}
|
||||
|
||||
@ -485,9 +457,9 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
acl::server_socket ss; // 监听套接口对象
|
||||
|
||||
// 监听指定地址
|
||||
if (ss.open(addr) == false)
|
||||
{
|
||||
if (ss.open(addr) == false) {
|
||||
printf("listen %s error %s\r\n", addr, acl::last_serror());
|
||||
return 1;
|
||||
}
|
||||
@ -495,7 +467,7 @@ int main(int argc, char *argv[])
|
||||
printf("listen %s ok\r\n", addr);
|
||||
|
||||
// 创建服务器接收连接协程
|
||||
go[&] {
|
||||
go_share(8192)[&] {
|
||||
fiber_accept(ss);
|
||||
};
|
||||
|
||||
|
@ -128,14 +128,22 @@ public:
|
||||
|
||||
void wait_exit(void)
|
||||
{
|
||||
#ifdef USE_CHAN
|
||||
int mtype;
|
||||
chan_exit_.pop(mtype);
|
||||
#else
|
||||
chan_exit_.pop();
|
||||
#endif
|
||||
}
|
||||
|
||||
void notify_exit(void)
|
||||
{
|
||||
#ifdef USE_CHAN
|
||||
int mtype = MT_LOGOUT;
|
||||
chan_exit_.put(mtype);
|
||||
#else
|
||||
chan_exit_.push(NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
void set_reader(void)
|
||||
@ -152,10 +160,11 @@ private:
|
||||
acl::socket_stream& conn_;
|
||||
#ifdef USE_CHAN
|
||||
acl::channel<int> chan_msg_;
|
||||
acl::channel<int> chan_exit_;
|
||||
#else
|
||||
acl::fiber_sem sem_msg_;
|
||||
acl::fiber_tbox<bool> chan_exit_;
|
||||
#endif
|
||||
acl::channel<int> chan_exit_;
|
||||
acl::string name_;
|
||||
std::list<acl::string*> messages_;
|
||||
bool exiting_ = false;
|
||||
|
0
lib_fiber/samples/chat/server/valgrind.sh
Normal file → Executable file
0
lib_fiber/samples/chat/server/valgrind.sh
Normal file → Executable file
@ -49,7 +49,8 @@ static void test_file(void) {
|
||||
|
||||
class fiber_server : public acl::fiber {
|
||||
public:
|
||||
fiber_server(acl::server_socket& ss) : ss_(ss) {}
|
||||
fiber_server(acl::server_socket& ss, bool stack_share)
|
||||
: ss_(ss), stack_share_(stack_share) {}
|
||||
~fiber_server(void) {}
|
||||
|
||||
protected:
|
||||
@ -68,45 +69,50 @@ protected:
|
||||
// create one fiber for one connection
|
||||
fiber_client* fc = new fiber_client(conn);
|
||||
// start the client fiber
|
||||
fc->start();
|
||||
fc->start(stack_share_ ? 8000 : 32000, stack_share_);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
acl::server_socket& ss_;
|
||||
bool stack_share_;
|
||||
};
|
||||
|
||||
class thread_server : public acl::thread {
|
||||
public:
|
||||
thread_server(acl::server_socket& ss) : ss_(ss) {}
|
||||
thread_server(acl::server_socket& ss, bool stack_share)
|
||||
: ss_(ss), stack_share_(stack_share) {}
|
||||
~thread_server(void) {}
|
||||
|
||||
protected:
|
||||
void* run(void) {
|
||||
fiber_server fs(ss_);
|
||||
fs.start(); // start listen fiber
|
||||
fiber_server fs(ss_, stack_share_);
|
||||
|
||||
// start listen fiber
|
||||
fs.start(stack_share_ ? 8000 : 32000, stack_share_);
|
||||
|
||||
acl::fiber::schedule(); // start fiber schedule
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
acl::server_socket& ss_;
|
||||
bool stack_share_;
|
||||
};
|
||||
|
||||
static void usage(const char* procname) {
|
||||
printf("usage: %s -h [help] -s listen_addr -t nthreads\r\n", procname);
|
||||
printf("usage: %s -h [help] -s listen_addr -t nthreads -S [if use stack sharing]\r\n", procname);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int ch, nthreads = 1;
|
||||
bool stack_share = false;
|
||||
|
||||
acl::acl_cpp_init();
|
||||
acl::string addr("127.0.0.1:9006");
|
||||
acl::log::stdout_open(true);
|
||||
|
||||
while ((ch = getopt(argc, argv, "hs:t:")) > 0) {
|
||||
while ((ch = getopt(argc, argv, "hs:t:S")) > 0) {
|
||||
switch (ch) {
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
@ -117,6 +123,9 @@ int main(int argc, char *argv[]) {
|
||||
case 't':
|
||||
nthreads = atoi(optarg);
|
||||
break;
|
||||
case 'S':
|
||||
stack_share = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -132,7 +141,7 @@ int main(int argc, char *argv[]) {
|
||||
std::vector<acl::thread*> threads;
|
||||
|
||||
for (int i = 0; i < nthreads; i++) {
|
||||
acl::thread* thread = new thread_server(ss);
|
||||
acl::thread* thread = new thread_server(ss, stack_share);
|
||||
thread->start();
|
||||
threads.push_back(thread);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user