SlideShare a Scribd company logo
1 of 117
C++11 features
used in Crow
Crow를 통해 살펴보는 C++11의 새 기능
하재승
@ipkn
ipknhama@gmail.com
Crow Framework을 작성하기 위해
사용한 기법들을 소개 (TMP 중심)
auto, lambda등
일반적인 C++ 개발에서 접하기 쉬운
기법들에 대한 설명은 생략
목표
목표
Crow
C++ Framework for writing Web server
http://github.com/ipkn/crow
GitHub Star 1251개
Hacker News vote 194
https://news.ycombinator.com/item?id=8002604
Web server 개념
브라우저로 접속해서 요청을 보내면
해당 요청에 맞는 응답을 보내줌
GET / HTTP/1.1
Host: www.example.com
HTTP/1.1 200 OK
Content-Length: 12
...
Hello World!
간단한 Crow 예제
#include “crow_all.h”
int main() {
crow::SimpleApp app;
CROW_ROUTE(app, “/”)
([]{
return “Hello world!”;
});
app.port(8080).run();
return 0;
}
… as Flask (from Quickstart)
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run()
목차
Routing
Compile time
Run time
Middleware
서버 구조
소개될 C++11 기능
template metaprogramming
constexpr
variadic template
SFINAE
decltype, declval
std::chrono, operator ””, enum class
왜 굳이 C++로?
https://github.com/ipkn/crow-benchmark
C++?
빠른 속도
멀티 패러다임 언어
절차형 + OOP + Generic (template)
template
compile time code generation
vector<T> →
vector<int>, vector<string>
T는 컴파일 타임에 결정되어야 한다.
Quick Review - auto, lambda, move
auto get_answer = []{ return 42; };
auto x = get_answer();
SomeBigData f() { … }
v.push_back(f());
Crow 클래스 구조
App
Server
Connection
Router
Rule (TaggedRule)
Trie
Routing
Routing - CROW_ROUTE
어떤 요청에 어떤 응답을 줄지 지정
CROW_ROUTE(app, “/”)
CROW_ROUTE(app, “/post/all”)
CROW_ROUTE(app, “/post/<int>”)
CROW_ROUTE(app,
“/near/<double>/<double>”)
CROW_ROUTE 목표
쓰기 편하게
실수하기 어렵게
잘못된 핸들러를 주면 에러나게
빠르게
실제 함수 호출 시 오버헤드를 최소화
CROW_ROUTE 기능 (1)
여러 타입의 인자 지원
<int>
<uint>
<double>
<str>
<path>
CROW_ROUTE 기능 (2)
컴파일 시간에 핸들러 타입 체크
CROW_ROUTE(app, “/post/<int>”)
([](string a) …
([](int a, int b) …
([](int a) ...
CROW_ROUTE 기능 (3)
여러 종류의 핸들러 지원
[](…)
[](const request& req, …)
[](const request& req, response& res, …)
* 어떻게 여러 종류를 지원하는지에 관해선 나중에 설명 예정
실제 CROW_ROUTE 구현
#define CROW_ROUTE(app, url)
app.route<
crow::black_magic::get_parameter_tag(url)
>(url)
black_magic ???!!!
이름을 말할 수 없는 그분 (...)
app.route<get_parameter_tag(url)>(url)
핸들러 형태 체크 → 컴파일 타임 → 템플릿 인자
실행 중에 URL 체크 → 런타임 → 함수 인자
실제 CROW_ROUTE 구현 (2)
app.route<get_parameter_tag(url)>(url)
핸들러 형태 체크 → 컴파일 타임 → 템플릿 인자
실행 중에 URL 체크 → 런타임 → 함수 인자
실제 CROW_ROUTE 구현 (2)
app.route<get_parameter_tag(url)>(url)
핸들러 형태 체크 → 컴파일 타임 → 템플릿 인자
실행 중에 URL 체크 → 런타임 → 함수 인자
실제 CROW_ROUTE 구현 (2)
app.route<get_parameter_tag(url)>(url)
스트링 값(“abc” 등)은 템플릿 인자로 사용할
수 없음
url로 부터 인자에 대한 정보를 얻어
템플릿 인자로 넣을 수 있는 값으로 변환
템플릿 인자부터 ..
constexpr function
constexpr int fact(int n) {
return (n <= 1)
? 1
: fact(n-1)*n;
}
char arr[fact(5)];
constexpr
컴파일 타임에 계산할 수도 있는 함수 또는 값
cin >> n; cout << fact(n); // 런타임
fact(5) == 120, 컴파일 타임에 계산 가능
→ 배열의 크기, 템플릿 인자 등으로 사용 가능
string literal의 컴파일 타임 해쉬 계산
get_parameter_tag
URL 을 받아 인자 정보를 가지는 숫자로 변환
인자가 없는 경우 0
URL 인자는 5종류: <int>=1 <uint>=2 …
6진법으로 표현
(자세한 구현은 생략)
get_parameter_tag
“/”
“/post”
“/post/<int>”
“/near/<int>/<int>”
“/put_score/<double>”
“/wiki/<path>”
0
0
1
11
3
5
숫자에서 다시 타입 리스트 복원
0 → <>
1 → <int>
11 → <int, int>
13 → <double, int>
4 → <string>
5 → <string> * path도 타입은 string
black_magic::S
variadic template으로 타입 리스트를 구현
S<int, double, string> 이 가능
S<a,b>::push<c> === S<c, a, b>
S<a>::push_back<b> === S<a, b>
S<a,b,c>::rebind<Rule> === Rule<a,b,c>
black_magic::S<T…> 구현 (1)
template <typename ... T>
struct S {
template <typename U>
using push = S<U, T...>;
S<a,b>::push<c> === S<c, a, b>
* using A = B; === typedef B A;
black_magic::S<T…> 구현 (2)
template <typename ... T> struct S {
template
<template <typename ...> class U>
using rebind = U<T...>;
S<a,b,c>::rebind<Rule> == Rule<a,b,c>
black_magic::arguments<uint64_t>
get_parameter_tag 값을 타입 리스트로
arguments<0>::type == S<>
arguments<3>::type == S<double>
arguments<11>::type == S<int, int>
arguments 구현
template <uint64_t Tag> struct arguments {
using subarg =
typename arguments<Tag/6>::type;
using type =
typename subargs::template push<
typename single_tag_to_type<Tag%6>::type
>;
};
실제로 일어나는 일
argument<31>
subarg = arg<3>
type = subarg::push<int>
실제로 일어나는 일
argument<31>
subarg = S<double>
type = S<int, double>
arg<3>
subarg = arg<0> = S<>
type = S<>:push<double> = S<double>
partial template specialization
template <int N>
struct single_tag_to_type {};
template <>
struct single_tag_to_type<1> {
using type = int64_t;
};
// C++11은 아니지만..
arguments 구현
template <>
struct arguments<0> {
using type = S<>;
};
URL이 라우팅 규칙이 되기까지
get_parameter_tag(“/<int>/<int>”)
→ arguments<11>
→ S<int, int>
→ TaggedRule<int, int>
Router
vector<unique_ptr<BaseRule>> rules_;
Q&A for Routing 1
get_parameter_tag(“/<int>/<int>”)
→ arguments<11>
→ S<int, int>
→ TaggedRule<int, int>
실제 핸들러 호출하기
Routing 2
남은 문제
/v<uint>/<string>/<path>
“/v2/wiki/example/document”
TaggedRule<uint, string, string>
handler
[](uint32_t ver, string func, string path)
Rule, TaggedRule
최종적으로 호출될 핸들러를 가지고 있음
app.route 의 리턴 값
void handle(
const request& req,
response& res,
const routing_params& params)
Trie based routing
여러 rule 들의 URL을 모아서
요청이 들어왔을 때
어느 Rule에서 처리할 지 판단
트리 구조로 성능 향상
Trie example
GET statuses/home_timeline
GET statuses/retweets/:id
GET statuses/retweets_of_me
POST statuses/retweet/:id
(from Twitter REST API)
statuses/
retweethome_timeline
s/
_of_meuint
uint
/
GET statuses/home_timeline
GET statuses/retweets/:id
GET statuses/retweets_of_me
POST statuses/retweet/:id
Trie
add( string url, rule )
find( string url )
-> rule, routing_params
http://en.wikipedia.org/wiki/Trie
routing.h
routing_params
vector<int> int_params;
vector<uint> uint_params;
vector<double> double_params;
vector<string> string_params;
Trie example (1)
/near/<double>/<double>
“/near/37.1/10.1”
routing_params.double_params == {37.1, 10.1}
Trie example (2)
/v<uint>/<string>/<path>
“/v2/wiki/example/document”
routing_params
.uint_params == {2}
.string_params ==
{“wiki”, “example/document”}
핸들러 호출하기
/v<uint>/<string>/<path>
[](unsigned int, string, string)
handler(rp.uint_params[0],
rp.string_params[0],
rp.string_params[1])
compile time
호출부 구현
template <typename CP,
int NInt, int NUint, int NDouble, int NString,
typename S1, typename S2>
struct call;
S1 - URL로 부터 정의된 핸들러 인자 타입의 리스트
S2 - 호출을 위한 타입+인덱스 정보의 리스트
N?? - 인자 처리를 위한 인덱스 값들, CP - 호출 파라미터
TaggedRule<Args…>::handle
void handle(req, res, routing_params) {
call<CallParams, 0, 0, 0, 0, S<Args…>, S<>>(
call_params);
}
call_params
req + res + routing_params + handler
call 호출 과정 - /v<uint>/<string>/<path>
0 0 [uint, str, str] []
1 0 [str, str] [(uint, 0)]
1 1 [str] [(uint, 0) (str, 0)]
1 2 [] [(uint, 0) (str, 0) (str, 1)]
call을 재귀호출
NUint NStr S1 S2
call 호출 과정 - /v<uint>/<string>/<path>
0 0 [uint, str, str] []
NUint NStr S1 S2
call 호출 과정 - /v<uint>/<string>/<path>
0 0 [uint, str, str] []
→ 1 0 [str, str] [<uint, 0>]
NUint NStr S1 S2
struct call<CP, NInt, NUint, NDouble, NString,
S< int64_t, Args1...>, S<Args2...>> {
void operator()(CP cp) {
using pushed = typename S<Args2...>::
template push_back<call_pair<int64_t, NInt>>;
call<CP, NInt+1, NUint, NDouble, NString,
S<Args1...>, pushed>()(cp);
}
};
call 호출 과정 - /v<uint>/<string>/<path>
0 0 [uint, str, str] []
1 0 [str, str] [<uint, 0>]
→ 1 1 [str] [<uint, 0> <str, 0>]
NUint NStr S1 S2
call 호출 과정 - /v<uint>/<string>/<path>
0 0 [uint, str, str] []
1 0 [str, str] [<uint, 0>]
1 1 [str] [<uint, 0> <str, 0>]
→ 1 2 [] [<uint, 0>, <str, 0>, <str, 1>]
NUint NStr S1 S2
struct call<CP, NInt, NUint, NDouble, NString,
S<>, S<Args2...>> {
void operator()(CP cp) {
// 일부 생략
cp.res = cp.handler(
cp.routing_params.template get
<typename Args2::type>(Args2::pos) ...
);
cparams.res.end();
return;
T routing_params::get<T>(index)
template<> string
routing_params::get<string>(index) const
{
return string_params[index];
}
핸들러 호출하기
handler(rp.uint_params[0],
rp.string_params[0],
rp.string_params[1]);
handler(rp.get<uint>(0),
rp.get<string>(0),
rp.get<string>(1));
handler( rp.get<Args2::type>(Args2::pos)... )
핸들러 호출하기
Args… = <uint, 0>, <str, 0>, <str, 1>
handler( rp.get<Args::type>(Args::pos)... )
<uint,0>을 대입한 경우를 보면 = rp.get<uint>(0)
...을 통해서 반복되므로
rp.get<uint>(0), rp.get<str>(1), rp.get<str>(2)
struct call<CP, NInt, NUint, NDouble, NString,
S<>, S<Args2...>> {
void operator()(CP cp) {
// 일부 생략
cp.res = cp.handler(
cp.routing_params.template get
<typename Args2::type>(Args2::pos) ...
);
cparams.res.end();
return;
Variadic template from example
void print(A a, B b, C c, …)
모든 인자를 출력해주는 함수
print()
print(1) - 1
print(2, “hello”, 40) - 2hello40
print 구현
void print() {}
template <typename A, typename ... Args>
void print(A a, Args... args)
{
cout << a;
print(args...);
}
print(2, “hello”, 40) 실행
A = int
Args… = const char*, int
args… = “hello”, 40
cout << 2;
print(“hello”, 40);
print 실행
print<int, const char*, int>(2, “hello”, 40) - 2
print<const char*, int>(“hello”, 40) - hello
print<int>(40) - 40
print()
2hello40
Variadic template 대입의 예
args… = 1, 5, 10
(args+1)… = 1+1, 5+1, 10+1
func(args)… = func(1), func(5), func(10)
func(args…) = func(1, 5, 10)
Q&A for Routing 2
Trie
Routing parameter
Variadic template
Middleware
Middleware?
C 요청 -> S 응답 -> C 받음
요청 --[MW]--> 응답 --[MW]--> 받음
before_handle(req, res)
after_handle(req, res)
Example Middleware
Static page serving (cache control)
Cookie parsing, Session support
JSON parsing
Profiling, Logging
Middleware of express.js (Node.js)
app.use(function (req, res, next) {
req.cookies = parse_cookies(req);
next();
});
// req에 임의로 변수추가 가능
Middleware 구현의 제약들
근데 우린 C++이잖아… 변수는 다 선언되어야
unordered_map<string, any> ???
+ express의 문제점: Dependency
세션은 사용하는데 쿠키파서가 없는 경우
이 문제를 어떻게 해결하면 좋을까?
각 MW별로 저장해야할 값들이 존재
어떤 MW는 다른 MW의 값을 참조해야 한다
(C++이니까)
필요한 MW가 빠진 경우 컴파일 에러가 발생해
야함
struct MW::context
MW가 필요한 값을 저장하는 struct
내용에 특별한 제한이 없음
App<A, B, C> app;
A, B, C 세 MW를 사용하는 app
SimpleApp == App<>
Crow에서의 해결 방식
ctx_A : public A::context
ctx_AB : public ctx_A, public B::context
ctx_ABC : public ctx_AB, public C::context
context : public ctx_ABC
실제로 ctx_AB === partial_context<A, B>
context 체인 상속 - App<A, B, C>
Crow에서의 해결 방식
template <typename AllContext>
before_handle(req, res, context& ctx,
AllContext& all_ctx)
from MW - all_ctx.get<A>()
from handler - app.get_context<A>(req)
Crow에서의 해결 방식 - 전체 호출 과정
A::before_handle(req, res, ctx_A)
B::before_handle(req, res, ctx_AB)
C::before_handle(req, res, ctx_ABC)
app.handle(req, res)
C::after_handle(req, res, ctx_ABC)
B::after_handle(req, res, ctx_AB)
A::after_handle(req, res, ctx_A)
Dependency 해결 (1)
Session MW는 Cookie MW에 의존한다면
app<Cookie, Session> - OK
app<Session> - error
app<Session, Cookie> - error
의존: all_ctx.get<Cookie>를 사용한다.
Dependency 해결 (2)
App<A, B, C> app;
A::before_handle(req, res, ctx_A)
B::before_handle(req, res, ctx_AB)
C::before_handle(req, res, ctx_ABC)
app.handle(req, res)
C::after_handle(req, res, ctx_ABC)
B::after_handle(req, res, ctx_AB)
A::after_handle(req, res, ctx_A)
Dependency 해결 (3)
ctx_A :: get<A> - OK
ctx_A :: get<B> - error
ctx_AB :: get<A> - OK
ctx_AB :: get<B> - OK
ctx_AB::get
template <typename T>
typename T::context& get() {
return
static_cast<typename T::context&>(*this);
}
상속한 MW의 context 타입으로만 캐스팅 가능
다른 MW과 연관이 없는 MW라면?
template <typename AllContext>
before_handle(req, res,
context& ctx, AllContext& all_ctx)
대부분의 경우
before_handle(req, res, context& ctx)
SFINAE
Substitution failure is not an error.
템플릿 인자를 대입하는 과정에서 발생하는 에
러는 에러로 간주하지 않는다. (모두 실패하는
경우에는 에러)
또는 이를 이용한 프로그래밍 기법을 지칭함
SFINAE 예제
template <typename T>
true_type has_iterator_checker(typename T::iterator *);
template <typename T>
false_type has_iterator_checker(...);
decltype(has_iterator_checker<int>()) === false_type
decltype(has_iterator_checker<string>()) === true_type
template <typename MW>
struct check_before_handle_arity_3
{
template <typename T,
void(T::*)(request&,response&,MW::context&)
= &T::before_handle
>
struct get {};
};
template <typename T>
struct is_before_handle_arity_3_impl
{
template <typename C>
static std::true_type
f(check_before_handle_arity_3<T>::get<C>*);
template <typename C>
static std::false_type f(...);
public:
static const bool value = decltype(f<T>(nullptr))::value;
};
std::enable_if
SFINAE를 이용하기 편하게 만들어둔 도구
조건부로 구현을 선택
template <typename T>
enable_if<is_integral<T>::value> func(T x) …
handler 형태를 고를 때 사용 (생략)
http://en.cppreference.com/w/cpp/types/enable_if
CookieParser - Example Middleware
CookieParser::context
uo_map<string, string> jar,
cookies_to_add;
get_cookie(key)
set_cookie(key, value)
before - 파싱 + jar에 저장
after - Set-Cookie 헤더 추가
Q&A for Middleware
App<A, B, C> app;
context inheritance chain
Middleware call chain
CookieParser
SFINAE
Crow 서버 구조
고려해야 할 점
멀티 쓰레드 작업 배분
Connection 객체의 생성, 소멸 관리
HTTP 타임 아웃 (Keep-Alive)
초기 버전
boost::asio + joyent/http-parser
asio::io_service 하나
concurrency 개수 만큼 io_service.run()
shared_ptr<Connection> 으로 수명 관리
asio::deadline_timer로 타임아웃 처리
초당 처리 횟수가 100,000 이상..
shared_ptr의 atomic 연산이 성능 부하
deadline_timer 내부 자료구조 업데이트 부하
여러 개의 싱글 쓰레드 서버의 결합
N 개의 작업용 쓰레드 (asio::io_service ✕ N)
요청이 들어올 때마다
어느 쓰레드가 처리할지 RR로 분배
해당 요청에 대한 모든 처리는
담당한 쓰레드 안에서만 이루어짐
deadline_timer 성능 저하 문제
각 쓰레드 별로 thread_local한 타이머를 구현
관련 코드: dumb_timer_queue.h
shared_ptr 제거
Connection 객체를 하나의 쓰레드가 담당
atomic 연산 불필요
변경 후 성능 4배 향상
쓰레드간 통신 전혀 없음
* shared_ptr을 쓰지말란 얘기는 아닙니다.
그 외 사용된
C++11 기능들 소개
std::chrono
std::chrono::
system_clock
steady_clock
high_resolution_clock
(거의) 같은 인터페이스 제공
std::chrono 사용법
auto t1 = clock::now();
do_something();
auto t2 = clock::now();
if (t2 - t1 > seconds(10)) …
duration_cast<seconds>(t2 - t1).count()
system_clock
to_time_t, from_time_t 제공
steady_clock
무조건 증가함이 보장됨
high_resolution_clock
제일 높은 해상도를 제공
(가능한 짧은 시간 간격)
operator “”
C++11
std::chrono::seconds(10)
std::chrono::minutes(20)
std::string(“hello”)
C++14
10s
20min
“hello”s
POST request
CROW_ROUTE(app, “/update_score”)
.methods(“POST”_method)
([](const crow::request& req){
auto json = crow::json::load(req.body);
...
});
operator “” _method
constexpr crow::HTTPMethod operator ""
_method(const char* str, size_t len)
{
return
crow::black_magic::is_equ_p(str, "GET", 3)
? crow::HTTPMethod::GET :
…
};
enum class
enum class HTTPMethod
{
GET,
POST,
...
};
int m = HTTPMethod::GET; // error!
decltype, declval<T>
decltype(X)
X의 선언형
declval<T>()
컴파일 타임에만 사용할 수 있는 T의 객체형
template <typename A, typename B>
auto add(A a, B b) -> decltype(a+b)
{ return a+b; }
template <typename A, typename B>
decltype(declval<A>() + declval<B>())
add(A a, B b)
C++14: return type deduction
<끝>(내용 발표는)
C++14 - minor patch to 11
Function return type deduction
Relaxed constexpr
Variable template
Lambda capture expression
Generic lambda
auto lambda = [a = 3](auto x, auto y)
{return a + x + y;};
C++14 - minor patch to 11
그외 …
01010b, 1’234’5678’9 == 123456789
make_unique
...
C++14 - minor patch는 훼이크
auto p = [](auto& s, auto...x){
[](...){}((s<<x,1)...);
};
p(cout, 42, "hello?");
위 코드의 실행 결과를 설명하시오. (3점)
VS2015 RC C++11 지원
http://blogs.msdn.com/b/vcblog/archive/2015/04/29/c-
11-14-17-features-in-vs-2015-rc.aspx
ref-qualifiers(멤버함수 뒤 &&)
Inheriting constructors
u8"한글", char16_t , char32_t
struct B1 {
B1( int );
};
struct D1 : B1 {
using B1::B1;
};

More Related Content

What's hot

자동화된 소스 분석, 처리, 검증을 통한 소스의 불필요한 #if - #endif 제거하기 NDC2012
자동화된 소스 분석, 처리, 검증을 통한 소스의 불필요한 #if - #endif 제거하기 NDC2012자동화된 소스 분석, 처리, 검증을 통한 소스의 불필요한 #if - #endif 제거하기 NDC2012
자동화된 소스 분석, 처리, 검증을 통한 소스의 불필요한 #if - #endif 제거하기 NDC2012
Esun Kim
 
임태현, MMO 서버 개발 포스트 모템, NDC2012
임태현, MMO 서버 개발 포스트 모템, NDC2012임태현, MMO 서버 개발 포스트 모템, NDC2012
임태현, MMO 서버 개발 포스트 모템, NDC2012
devCAT Studio, NEXON
 
[NDC07] 게임 개발에서의 클라이언트 보안 - 송창규
[NDC07] 게임 개발에서의 클라이언트 보안 - 송창규[NDC07] 게임 개발에서의 클라이언트 보안 - 송창규
[NDC07] 게임 개발에서의 클라이언트 보안 - 송창규
ChangKyu Song
 

What's hot (20)

자동화된 소스 분석, 처리, 검증을 통한 소스의 불필요한 #if - #endif 제거하기 NDC2012
자동화된 소스 분석, 처리, 검증을 통한 소스의 불필요한 #if - #endif 제거하기 NDC2012자동화된 소스 분석, 처리, 검증을 통한 소스의 불필요한 #if - #endif 제거하기 NDC2012
자동화된 소스 분석, 처리, 검증을 통한 소스의 불필요한 #if - #endif 제거하기 NDC2012
 
MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현
 
NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기
NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기
NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기
 
빌드관리 및 디버깅 (2010년 자료)
빌드관리 및 디버깅 (2010년 자료)빌드관리 및 디버깅 (2010년 자료)
빌드관리 및 디버깅 (2010년 자료)
 
NDC12_Lockless게임서버설계와구현
NDC12_Lockless게임서버설계와구현NDC12_Lockless게임서버설계와구현
NDC12_Lockless게임서버설계와구현
 
[NDC 2018] 유체역학 엔진 개발기
[NDC 2018] 유체역학 엔진 개발기[NDC 2018] 유체역학 엔진 개발기
[NDC 2018] 유체역학 엔진 개발기
 
C++20 Key Features Summary
C++20 Key Features SummaryC++20 Key Features Summary
C++20 Key Features Summary
 
GCGC- CGCII 서버 엔진에 적용된 기술 (1)
GCGC- CGCII 서버 엔진에 적용된 기술 (1)GCGC- CGCII 서버 엔진에 적용된 기술 (1)
GCGC- CGCII 서버 엔진에 적용된 기술 (1)
 
[NDC2016] TERA 서버의 Modern C++ 활용기
[NDC2016] TERA 서버의 Modern C++ 활용기[NDC2016] TERA 서버의 Modern C++ 활용기
[NDC2016] TERA 서버의 Modern C++ 활용기
 
게임서버프로그래밍 #8 - 성능 평가
게임서버프로그래밍 #8 - 성능 평가게임서버프로그래밍 #8 - 성능 평가
게임서버프로그래밍 #8 - 성능 평가
 
[143] Modern C++ 무조건 써야 해?
[143] Modern C++ 무조건 써야 해?[143] Modern C++ 무조건 써야 해?
[143] Modern C++ 무조건 써야 해?
 
C++ Programming - 1st Study
C++ Programming - 1st StudyC++ Programming - 1st Study
C++ Programming - 1st Study
 
GCGC- CGCII 서버 엔진에 적용된 기술 (2) - Perfornance
GCGC- CGCII 서버 엔진에 적용된 기술 (2) - PerfornanceGCGC- CGCII 서버 엔진에 적용된 기술 (2) - Perfornance
GCGC- CGCII 서버 엔진에 적용된 기술 (2) - Perfornance
 
임태현, MMO 서버 개발 포스트 모템, NDC2012
임태현, MMO 서버 개발 포스트 모템, NDC2012임태현, MMO 서버 개발 포스트 모템, NDC2012
임태현, MMO 서버 개발 포스트 모템, NDC2012
 
Windows Registered I/O (RIO) vs IOCP
Windows Registered I/O (RIO) vs IOCPWindows Registered I/O (RIO) vs IOCP
Windows Registered I/O (RIO) vs IOCP
 
코딩 테스트 및 알고리즘 문제해결 공부 방법 (고려대학교 KUCC, 2022년 4월)
코딩 테스트 및 알고리즘 문제해결 공부 방법 (고려대학교 KUCC, 2022년 4월)코딩 테스트 및 알고리즘 문제해결 공부 방법 (고려대학교 KUCC, 2022년 4월)
코딩 테스트 및 알고리즘 문제해결 공부 방법 (고려대학교 KUCC, 2022년 4월)
 
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들
 
[2013 CodeEngn Conference 09] Park.Sam - 게임 해킹툴의 변칙적 공격 기법 분석
[2013 CodeEngn Conference 09] Park.Sam - 게임 해킹툴의 변칙적 공격 기법 분석[2013 CodeEngn Conference 09] Park.Sam - 게임 해킹툴의 변칙적 공격 기법 분석
[2013 CodeEngn Conference 09] Park.Sam - 게임 해킹툴의 변칙적 공격 기법 분석
 
Iocp 기본 구조 이해
Iocp 기본 구조 이해Iocp 기본 구조 이해
Iocp 기본 구조 이해
 
[NDC07] 게임 개발에서의 클라이언트 보안 - 송창규
[NDC07] 게임 개발에서의 클라이언트 보안 - 송창규[NDC07] 게임 개발에서의 클라이언트 보안 - 송창규
[NDC07] 게임 개발에서의 클라이언트 보안 - 송창규
 

Viewers also liked

[NDC2015] 언제 어디서나 프로파일링 가능한 코드네임 JYP 작성기 - 라이브 게임 배포 후에도 프로파일링 하기
[NDC2015] 언제 어디서나 프로파일링 가능한 코드네임 JYP 작성기 - 라이브 게임 배포 후에도 프로파일링 하기[NDC2015] 언제 어디서나 프로파일링 가능한 코드네임 JYP 작성기 - 라이브 게임 배포 후에도 프로파일링 하기
[NDC2015] 언제 어디서나 프로파일링 가능한 코드네임 JYP 작성기 - 라이브 게임 배포 후에도 프로파일링 하기
Jaeseung Ha
 
Boost 라이브리와 C++11
Boost 라이브리와 C++11Boost 라이브리와 C++11
Boost 라이브리와 C++11
OnGameServer
 
Physics for Game Programmers
Physics for Game ProgrammersPhysics for Game Programmers
Physics for Game Programmers
Ung-Su Lee
 

Viewers also liked (20)

20150212 c++11 features used in crow
20150212 c++11 features used in crow20150212 c++11 features used in crow
20150212 c++11 features used in crow
 
[NDC2015] 언제 어디서나 프로파일링 가능한 코드네임 JYP 작성기 - 라이브 게임 배포 후에도 프로파일링 하기
[NDC2015] 언제 어디서나 프로파일링 가능한 코드네임 JYP 작성기 - 라이브 게임 배포 후에도 프로파일링 하기[NDC2015] 언제 어디서나 프로파일링 가능한 코드네임 JYP 작성기 - 라이브 게임 배포 후에도 프로파일링 하기
[NDC2015] 언제 어디서나 프로파일링 가능한 코드네임 JYP 작성기 - 라이브 게임 배포 후에도 프로파일링 하기
 
[NDC 2014] 던전앤파이터 클라이언트 로딩 최적화
[NDC 2014] 던전앤파이터 클라이언트 로딩 최적화[NDC 2014] 던전앤파이터 클라이언트 로딩 최적화
[NDC 2014] 던전앤파이터 클라이언트 로딩 최적화
 
Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이 왜 이리 힘드나요? (Lock-free에서 Transactional Memory까지)
Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이  왜 이리 힘드나요?  (Lock-free에서 Transactional Memory까지)Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이  왜 이리 힘드나요?  (Lock-free에서 Transactional Memory까지)
Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이 왜 이리 힘드나요? (Lock-free에서 Transactional Memory까지)
 
NDC 11 자이언트 서버의 비밀
NDC 11 자이언트 서버의 비밀NDC 11 자이언트 서버의 비밀
NDC 11 자이언트 서버의 비밀
 
Boost 라이브리와 C++11
Boost 라이브리와 C++11Boost 라이브리와 C++11
Boost 라이브리와 C++11
 
[NHN NEXT 14] [Pl in c++] 1. 수업 내용 및 진행 방법
[NHN NEXT 14] [Pl in c++] 1. 수업 내용 및 진행 방법[NHN NEXT 14] [Pl in c++] 1. 수업 내용 및 진행 방법
[NHN NEXT 14] [Pl in c++] 1. 수업 내용 및 진행 방법
 
Visual c++ 오목게임제작
Visual c++ 오목게임제작Visual c++ 오목게임제작
Visual c++ 오목게임제작
 
C++11(최지웅)
C++11(최지웅)C++11(최지웅)
C++11(최지웅)
 
c++11
c++11c++11
c++11
 
C++11
C++11C++11
C++11
 
[C++ adv] c++11
[C++ adv] c++11[C++ adv] c++11
[C++ adv] c++11
 
C++ 타입 추론
C++ 타입 추론C++ 타입 추론
C++ 타입 추론
 
Ndc12 2
Ndc12 2Ndc12 2
Ndc12 2
 
초보를 위한 C++11
초보를 위한 C++11초보를 위한 C++11
초보를 위한 C++11
 
Physics for Game Programmers
Physics for Game ProgrammersPhysics for Game Programmers
Physics for Game Programmers
 
NDC 2011 이은석 - 마비노기 영웅전 아트 디렉팅
NDC 2011 이은석 - 마비노기 영웅전 아트 디렉팅NDC 2011 이은석 - 마비노기 영웅전 아트 디렉팅
NDC 2011 이은석 - 마비노기 영웅전 아트 디렉팅
 
[UNITE2014] 개발과 출시 경험에 대한 이야기
[UNITE2014] 개발과 출시 경험에 대한 이야기[UNITE2014] 개발과 출시 경험에 대한 이야기
[UNITE2014] 개발과 출시 경험에 대한 이야기
 
DirectX + C++을 이용한 WindowsStore App과 Windows Phone용 게임 개발
DirectX + C++을 이용한  WindowsStore App과 Windows Phone용 게임 개발DirectX + C++을 이용한  WindowsStore App과 Windows Phone용 게임 개발
DirectX + C++을 이용한 WindowsStore App과 Windows Phone용 게임 개발
 
Moving NEON to 64 bits
Moving NEON to 64 bitsMoving NEON to 64 bits
Moving NEON to 64 bits
 

Similar to [NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로

Javascript개발자의 눈으로 python 들여다보기
Javascript개발자의 눈으로 python 들여다보기Javascript개발자의 눈으로 python 들여다보기
Javascript개발자의 눈으로 python 들여다보기
지수 윤
 
KTH_Detail day_화성에서 온 개발자 금성에서 온 기획자 시리즈_5차_데이터분석_조범석_20120613
KTH_Detail day_화성에서 온 개발자 금성에서 온 기획자 시리즈_5차_데이터분석_조범석_20120613KTH_Detail day_화성에서 온 개발자 금성에서 온 기획자 시리즈_5차_데이터분석_조범석_20120613
KTH_Detail day_화성에서 온 개발자 금성에서 온 기획자 시리즈_5차_데이터분석_조범석_20120613
KTH, 케이티하이텔
 
C Language I
C Language IC Language I
C Language I
Suho Kwon
 
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
Sang Don Kim
 
사례를 통해 살펴보는 프로파일링과 최적화 NDC2013
사례를 통해 살펴보는 프로파일링과 최적화 NDC2013사례를 통해 살펴보는 프로파일링과 최적화 NDC2013
사례를 통해 살펴보는 프로파일링과 최적화 NDC2013
Esun Kim
 
MapReduce 실행 샘플 (K-mer Counting, K-means Clustering)
MapReduce 실행 샘플 (K-mer Counting, K-means Clustering)MapReduce 실행 샘플 (K-mer Counting, K-means Clustering)
MapReduce 실행 샘플 (K-mer Counting, K-means Clustering)
주영 송
 

Similar to [NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로 (20)

프로그래밍 대회: C++11 이야기
프로그래밍 대회: C++11 이야기프로그래밍 대회: C++11 이야기
프로그래밍 대회: C++11 이야기
 
Javascript개발자의 눈으로 python 들여다보기
Javascript개발자의 눈으로 python 들여다보기Javascript개발자의 눈으로 python 들여다보기
Javascript개발자의 눈으로 python 들여다보기
 
6 function
6 function6 function
6 function
 
불어오는 변화의 바람, From c++98 to c++11, 14
불어오는 변화의 바람, From c++98 to c++11, 14 불어오는 변화의 바람, From c++98 to c++11, 14
불어오는 변화의 바람, From c++98 to c++11, 14
 
Deview 2019 눈발자국
Deview 2019 눈발자국Deview 2019 눈발자국
Deview 2019 눈발자국
 
포트폴리오에서 사용한 모던 C++
포트폴리오에서 사용한 모던 C++포트폴리오에서 사용한 모던 C++
포트폴리오에서 사용한 모던 C++
 
KTH_Detail day_화성에서 온 개발자 금성에서 온 기획자 시리즈_5차_데이터분석_조범석_20120613
KTH_Detail day_화성에서 온 개발자 금성에서 온 기획자 시리즈_5차_데이터분석_조범석_20120613KTH_Detail day_화성에서 온 개발자 금성에서 온 기획자 시리즈_5차_데이터분석_조범석_20120613
KTH_Detail day_화성에서 온 개발자 금성에서 온 기획자 시리즈_5차_데이터분석_조범석_20120613
 
06장 함수
06장 함수06장 함수
06장 함수
 
C++17 Key Features Summary - Ver 2
C++17 Key Features Summary - Ver 2C++17 Key Features Summary - Ver 2
C++17 Key Features Summary - Ver 2
 
//BUILD/ Seoul - .NET의 현재와 미래. 그 새로운 시작
//BUILD/ Seoul - .NET의 현재와 미래. 그 새로운 시작//BUILD/ Seoul - .NET의 현재와 미래. 그 새로운 시작
//BUILD/ Seoul - .NET의 현재와 미래. 그 새로운 시작
 
Java stream v0.1
Java stream v0.1Java stream v0.1
Java stream v0.1
 
Java stream v0.1
Java stream v0.1Java stream v0.1
Java stream v0.1
 
C Language I
C Language IC Language I
C Language I
 
Airflow를 이용한 데이터 Workflow 관리
Airflow를 이용한  데이터 Workflow 관리Airflow를 이용한  데이터 Workflow 관리
Airflow를 이용한 데이터 Workflow 관리
 
파이썬 스터디 2주차
파이썬 스터디 2주차파이썬 스터디 2주차
파이썬 스터디 2주차
 
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
 
[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기
[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기
[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기
 
사례를 통해 살펴보는 프로파일링과 최적화 NDC2013
사례를 통해 살펴보는 프로파일링과 최적화 NDC2013사례를 통해 살펴보는 프로파일링과 최적화 NDC2013
사례를 통해 살펴보는 프로파일링과 최적화 NDC2013
 
[Swift] Protocol (2/2)
[Swift] Protocol (2/2)[Swift] Protocol (2/2)
[Swift] Protocol (2/2)
 
MapReduce 실행 샘플 (K-mer Counting, K-means Clustering)
MapReduce 실행 샘플 (K-mer Counting, K-means Clustering)MapReduce 실행 샘플 (K-mer Counting, K-means Clustering)
MapReduce 실행 샘플 (K-mer Counting, K-means Clustering)
 

[NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로