future를 사용하면 비동기 IO 처리의 결과 값을 얻을 수 있다.

아래의 코드는 future를 사용하여 UDP로 보내기와 받기를 하고 있다. future를 사용하고 있어서 비동기 완료 함수를 지정하지 않아도 된다.




( 완전한 코드는 'AsynchronousUDPClient_future' 프로젝트에 있다. )


AsynchronousUDPClient_future.zip


저작자 표시
신고
by 흥배 2014.06.30 08:00

MS Build 컨퍼런스에서 Visual C++의 C++ 11 구현에 대한 이야기가 있었다.

작년에 나왔던 VC++ Nov 2013 CTP 다음 버전이 2~3개월 이내에 나올 예정이고 대부분의 C++11을 구현할 예정이라고 한다.

더해서 C++14 기능 중 일부도 구현될 예정이라고 한다.



좀 더 자세한 내용은 http://channel9.msdn.com/Events/Build/2014/2-661 를 보기 바란다.


저작자 표시
신고
by 흥배 2014.04.07 08:00

웹 서핑 중 C++11의 기능 중 Visual Studio 2013에도 추가된 'Non-static data member initializers, Variadic templates, Initializer lists, Alias templates' 기능을 맛 볼 수 있는 코드를 보아서 소개한다.

 

테스트는 간단하게 웹 컴파일러를 이용했다.

웹 컴파일러: http://melpon.org/wandbox/

 

코드(출처: http://d.hatena.ne.jp/osyo-manga/20131027/1382882447 )

#include <iostream>

#include <vector>

#include <string>

 

// Variadic templates

template<typename... Args>

void func(Args... args)

{

// Initializer lists

for(auto&& n : { args... })

{

std::cout << n << std::endl;

}

}

 

template<typename T>

struct X

{

T value;

X(int n) : value(n){}

};

 

struct person

{

// Non-static data member initializers

int age = 13;

std::string name = "homu";

};

 

 

// Aliases templates

template<typename T>

using my_vector = std::vector<X<T>>;

 

int main()

{

std::cout << "Aliases templates, Initializer lists" << std::endl;

my_vector<int> v = { X<int>{1}, X<int>{2}, X<int>{3}};

 

for(auto&& n : v)

{

std::cout << n.value << std::endl;

}

std::cout << std::endl;

 

 

std::cout << "Variadic templates" << std::endl;

func(1.1, 2.2, 3.3, 4.4, 5.5);

std::cout << std::endl;

 

 

std::cout << "Non-static data member initializers" << std::endl;

person homu;

std::cout << homu.name << std::endl;

std::cout << homu.age << std::endl;

 

return 0;

}

< 결과 >

 

위 코드는 Visual Studio 2013에서도 잘 돌아가며 VS 2013에서는 C++11 기능 중 아래의 것이 새롭게 구현 되었다.

Non-static data member initializers

Variadic templates

Initializer lists

Default template arguments for function templates

Alias templates

Delegating constructors

Explicit conversion operators

Raw string literals

Defaulted and deleted functions

 

더 자세한 정보는 http://msdn.microsoft.com/en-us/library/vstudio/hh567368.aspx 를 참고.

 

 

신고
by 흥배 2014.02.17 08:00

리눅스 환경에서 Clang으로 간단한 C++ 코드를 빌드해 본다.

 

먼저 리눅스는 OpenSUSE 13.1 버전이고 기본으로는 Clang이 설치 되어 있지 않아서 제어판(?)에서 설치한다.

아래의 메뉴에서 설치하면 가장 최신 버전을 설치하지는 못하지만(출시 주기가 길지 않은) 리눅스에 익숙하지 않은 사람에게는 아주 쉽게 프로그램을 설치할 수 있다.

 

검색으로 'Clang'을 입력하여 선택 후 설치한다.

 

터미널에서 gedit를 실행 후 간단한 C++ 코드를 만든다.

 

C++을 빌드해야 하기 때문에 gcc 와 비슷하게 'clang++'을 사용한다.

(사용 방법이 gcc와 거의 같다고 봐도 좋을 듯 하다)

 


C++11

hello.cpp

#include <iostream>

#include <array>


int main()

{

std::array<int, 5> a;

a[0] = 5;


std::cout << a[0] << std::endl;

return 0;

}


32bit

clang++ -m32 -std=c++11 -stdlib=libc++ hello.cpp

64bit

clang++ -m64 -std=c++11 -stdlib=libc++ hello.cpp


libc++ 라이브러리를 빌드하지 않았다면 '-stdlib=libc++'를 '-stdlib=libstdc++'로 바꾸어야 한다.


make 파일 사용 예

CXX=clang++

CXXFLAGS= -Wall -std=c++11


all:hello


clean:

rm -rf hello

rm -rf *.o





신고
by 흥배 2014.01.28 08:30

struct X

{

    std::mutex m;

    int a;

    std::string b;

};

 

void foo(X& a,X& b)

{

    a.m.lock();

    ....

           a.m.unlock();

          

           b.m.lock();

           ....

           b.m.unlock();

}

 

위의 코드에서

X x1, x2;

인스턴스를 생성 후

스레드 1에서 foo( x1, x2 )를 호출하고 동시에 스레드 2에서 f00( x2, x1 )를 호출하면 데드락 상황에 빠지게 됩니다.

 

위 코드는 작아서 이런 실수를 하지 않겠지만 몇 천, 몇 만 코드에서 여러 프로그래머가 같이 작업을 하다 보면 실수를 할 확률이 아주 높고, 문제가 발생하면 쉽게 찾기도 힘들기도 합니다.

 

이 문제를 방지하기 위해서 std::lock 이라는 함수가 있습니다. std::lock 함수를 사용하면 여러  뮤텍스를 동시에 락을 걸 수 있습니다. 아래와 같이

 

std::lock( a.m, b.m );

 

정의는 아래와 같습니다.

template<class L1, class L2, class... L3>

   void lock(L1&, L2&, L3&...);

  

 

 

보통 좀 더 안전하게 뮤텍스를 사용하기 위해서 보통 unique_lock과 같이 사용하는 편입니다.

 

void foo(X& a,X& b)

{

    std::unique_lock<std::mutex> lock_a(a.m,std::defer_lock);

    std::unique_lock<std::mutex> lock_b(b.m,std::defer_lock);

   

           std::lock(lock_a,lock_b);

 

    // 공유 자원을 사용한다

}

 

 

 

저작자 표시
신고
by 흥배 2013.08.26 08:30

XCode 4.6에서 만약 C++11 기능이 컴파일 되지 않는다면 ㅋ컴파일러 설정을 아래와 같이 변경한다.


Build Settings

- Apple LLVM compiler 4.2 -Language 카테고리에서

C++ Language Dialect 는 GNU++11 [-std=gnu++11] 로 변경하고

C++ Standard Library는 libc++ (LLVM C++ standard library with C++11 support) 로 변경한다

저작자 표시
신고
by 흥배 2013.08.16 13:56

리눅스 플랫폼에서 C++ 프로그래밍을 쉽게 하는 방법은 Eclipse라는 IDE를 사용하면 좋다.

그러나 VS를 사용했던 프로그래머로서는 사용해 보면 초반부터 간단한 부분에서 막혀서 스트레스를 받는데 이중 몇 가지를 기록 차원에서 간단하게 정리한다.


프로젝트 설정을 위해서는 아래의 설정 창을 열어야 한다.


C++11 사용하기

아래 처럼 -std=c++11 을 입력한다(참고로 gcc 4.8 사용)

* 참고  

Eclipse 에서 MinGW GCC 컴파일러로 C++11 사용하기

http://blog.powerumc.kr/404


외부 해더 파일 설정


외부 lib 파일 설정

여기서 주의할 점은 아래와 같이 이름이 libboost_reggex.a 라는 lib 파일을 설정에 등록할 때는 앞의 'lib'과 뒤의 '.a'를 제외하고 입력해야 한다.

*참고

eclipse에서 boost 사용하는데 에러가 난다..

http://abipictures.tistory.com/821


How to Install, Build and Use the Boost C++ libraries for development with the Eclipse IDE using the MinGW compiler on a Windows Platform 

http://theseekersquill.wordpress.com/2010/08/24/howto-boost-mingw/



std::thread 사용

아래처럼 '-pthread' 를 입력한다.

* 참고

How to make CDT/Eclipse work with C++11 threads?

http://stackoverflow.com/questions/10395936/how-to-make-cdt-eclipse-work-with-c11-threads



Eclipse는 VS와 다르게 빌드할 때 소스를 자동으로 저장하지 않는다.

그래서 코딩 후 저장하지 않고 빌드하면 빌드 실패가 발생한다.

빌드할 때 자동 저장을 하기 위해서는 아래의 옵션을 체크한다.

출처: http://stormcoding.tistory.com/6



저작자 표시
신고
by 흥배 2013.08.15 08:00

지금의 C++ 표준은 03 이 아닌 C++11 이다. 새로운 시대에 맞게 Asio 프로그래밍을 할 때 C++11 표준을 사용하는 것이 좋다.

 

C++03 표준을 사용하여 Asio를 사용할 때는 AsioAccept, Send, Receive 등의 비동기 함수에 완료 함수를 등록할 때 boost::bind를 사용하였지만 C++11 에서는 lambda를 사용한다.

 

Asio에서 리모트의 접속을 받아들이는 함수 async_accept C++03에서는 아래와 같은 방식으로사용했다.

 

boost::asio::ip::tcp::acceptor m_acceptor;

 

void handle_accept(Session* pSession, const boost::system::error_code& error)

{

if (!error)

{     

       std::cout << "클라이언트 접속 성공" << std::endl;

                   

       pSession->PostReceive();

}

}

 

m_acceptor.async_accept( m_pSession->Socket(),

                    boost::bind(&TCP_Server::handle_accept,

                           this,

                           m_pSession,

                           boost::asio::placeholders::error)

                    );

 

위의 코드를 C++11 방식으로 바꾸면 아래와 같다.

m_acceptor.async_accept( m_pSession->Socket(),

                     [this](boost::system::error_code error)

                    {

                       if (!error)

                       {  

                          std::cout << "클라이언트 접속 성공" << std::endl;

                          m_pSession->PostReceive();

                       }

                      

                       StartAccept();

                    }

                    );

 

 

 

저작자 표시
신고
by 흥배 2013.08.12 08:00

unique_lock는 쉽게 말하면 lock_guard에 기능이 더해진 것이라고 볼 수 있습니다.

lock_guard의 경우 정의와 동시에 락을 걸고, 파괴될 때만 락을 풀 수 있습니다.

 

그에 비해 unique_lock은 정의와 동시에 락을 걸 수도 있고, 또는 뒤에 락을 걸 수도 있습니다. 또 락을 푸는 것도 원하는 대로 조절이 가능하며 try_lock이나 try_lock_for, try_lock_until 등도 지원합니다. 그리고 unique_lock끼리 소유한 뮤텍스 객체를 서로 교환도 할 수 있으며, 뮤텍스 객체를 얻거나 해제할 수도 있습니다.

 

간단한 경우에는 lock_guard가 사용하기 편하지만 뮤텍스를 다양하게 사용하고 싶은 경우에는 unique_lock이 훨씬 더 좋습니다.

 

 

unique_lock 생성

unique_lock 클래스의 생성자는 다양한 방법으로 뮤텍스를 사용할 수 있도록 여러 버전이 준비 되어 있습니다.

 

unique_lock() noexcept;

unique_lock(unique_lock&& Other) noexcept;

explicit unique_lock(mutex_type& Mtx);

unique_lock(mutex_type& Mtx, adopt_lock_t Adopt);

unique_lock(mutex_type& Mtx, defer_lock_t Defer) noexcept;

unique_lock(mutex_type& Mtx, try_to_lock_t Try);

template<class Rep, class Period>

   unique_lock(mutex_type& Mtx,

      const chrono::duration<Rep, Period> Rel_time);

template<class Clock, class Duration>

   unique_lock(mutex_type& Mtx,

      const chrono::time_point<Clock, Duration> Abs_time);

unique_lock(mutex_type& Mtx,

   const xtime *Abs_time) noexcept;

 

unique_lock의 사용 예는 아래와 같습니다.

 

std::mutex m;

....

// 락을 만들고 동시에 뮤텍스의 소유권을 가진다

std::unique_lock lck(m, std::adopt_lock);

 

 

std::mutex m;

....

// 락을 만들지만 뮤텍스의 소유권은 가지지 않는다

std::unique_lock lck(m,std::defer_lock);      

...

if (lck.try_lock()) {

....

}                   

 

 

std::unique_lock<std::timed_mutex>

        lk(m,std::chrono::milliseconds(3));

....

if(lk) {

    process(data);

}                   

 

 

 

unique_lock 멤버 함수

 

- void lock();

- mutex_type *mutex() const _NOEXCEPT;

- explicit operator bool() _NOEXCEPT

- unique_lock& operator=(

    unique_lock&& Other

  ) _NOEXCEPT;

- bool owns_lock() const _NOEXCEPT;

- mutex_type *release() _NOEXCEPT;

- void swap(

    unique_lock& Other

  ) _NOEXCEPT;

- bool try_lock() _NOEXCEPT;

- template<class Rep,

    class Period>

  bool try_lock_for(

     const chrono::duration<Rep,

     Period>& Rel_time

  );

- template<class Clock, class Duration>

    bool try_lock_until(const chrono::time_point<Clock, Duration>& Abs_time);

    bool try_lock_until(const xtime *Abs_time);

- void unlock();

 

저작자 표시
신고
by 흥배 2013.07.15 08:00

근래 gcc나 Clang 등이 C++11 지원을 완료함에 따라서 기존에 C++03 방식으로 만들었던 C++ 프로그램에 조금씩 C++11 방식이 적용되고 있다.


얼마전에 Boost 라이브러리가 1.54 버전이 나왔는데 Asio 예제 코드를 03과 11 버전 두 가지로 나누어서 제공하고 있다.


http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/examples.html





http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/examples/cpp11_examples.html



이제 03 방식의 관습에서 벗어나서 C++11 방식으로 의식하면서 사용해야 할 것 같다



저작자 표시
신고
by 흥배 2013.07.11 08:00
| 1 2 3 4 5 ··· 7 |