'Study/C/C++'에 해당되는 글 6건

  1. 2016.02.03 explicit
  2. 2015.03.25 [boost] boost::asio::ip::tcp::socket에서 ip address 추출하는 방법
  3. 2015.03.09 [WinAPI] CriticalSection
  4. 2015.03.09 [C++11] Thread Pool
  5. 2015.03.09 Class의 멤버함수 포인터
  6. 2015.03.09 ERROR LINK2019

explicit

Study/C/C++ 2016. 2. 3. 15:19

위 코드를 보면 객체의 초기화가 다소 의아한 형태로 이루어지고있다. 컴파일 에러가 일어나지 않을까 싶은데 컴파일 에러가 일어나지 않는다. C++의 암시적 형변환 규칙에 따르면 생성자의 인자가 1개인 생성자들은 컴파일러에 의해 암시적 형변환에 동원되도록 되어있다. 따라서 위의 코드 같은 경우에는 해당 라인에서 A( 5 ) 라는 객체가 임시적으로 생성되어 컴파일러가 자동으로 생성해준 복사 할당 연산자에 의해 해당 객체가 복사가 되어 컴파일 에러 없이 프로그램이 수행이 될 수 있다.


허나, 위와같은 컴파일러의 처리는 프로그래머 입장에서는 의도치 않은 에러가 생길 여지가 있다. 특히 위와 같은 경우는 컴파일 에러가 나지 않기 때문에 위와 같은 경우로 버그가 생긴다면 찾기가 굉장히 힘들수도 있다. 이럴때 차라리 컴파일 에러가 난다면 좋지 않을까?


그래서 사용하는 것이 explicit 이다.



위 처럼 사용하면 main의 첫번째 라인에서 컴파일 에러가 발생한다. 이유는 explicit로 선언된 생성자는 암시적 형변환에 사용될 수 없기 때문이다. 프로그래머의 의도로 암시적 형변환을 사용하지 않는다면 explicit을 하는것이 좋을것같다.

'Study > C/C++' 카테고리의 다른 글

[boost] boost::asio::ip::tcp::socket에서 ip address 추출하는 방법  (0) 2015.03.25
[WinAPI] CriticalSection  (0) 2015.03.09
[C++11] Thread Pool  (0) 2015.03.09
Class의 멤버함수 포인터  (0) 2015.03.09
ERROR LINK2019  (0) 2015.03.09
Posted by BeraPP
,

TCP 서버측에서 자신과 연결된 클라이언트의 IP Address를 알고싶을 때 socket에서 IP Address를 추출하는 방법이다.

위와 같이 하면 IP Address를 std::string으로 추출할 수 있다.

'Study > C/C++' 카테고리의 다른 글

explicit  (0) 2016.02.03
[WinAPI] CriticalSection  (0) 2015.03.09
[C++11] Thread Pool  (0) 2015.03.09
Class의 멤버함수 포인터  (0) 2015.03.09
ERROR LINK2019  (0) 2015.03.09
Posted by BeraPP
,



위에것이 좋은게 공유자원에 접근중일 때 다른 접근이 없다면 세마포어를 생성하지 않는다.

Lock이 걸려있을 때 접근을 한다면 세마포어를 생성하고 대기상태로 들어간다.

락을 걸고있던 쓰레드가 일을 수행한 후 떠나면서 대기자를 깨워주고 나가게 된다.

혼자서 접근할때엔 세마포어를 생성하지 않기 때문에 성능이 좋다고한다.


InitializeCriticalSectionAndSpinCount 같은 경우에는 인자에 4000을 넣고있는데, 이것이 최대 대기하는 횟수? 라고한다. 점유되어 있는 자원에 대해 대기를 하는데 무한정 대기를 하면 안되는 경우가 있기 때문에 최대로 대기하는 횟수를 정하는 것이라 한다. 보통 4000을 많이 쓴다고 하는데 경우에 따라 바꿔주는것이 필요할듯 하다.

'Study > C/C++' 카테고리의 다른 글

explicit  (0) 2016.02.03
[boost] boost::asio::ip::tcp::socket에서 ip address 추출하는 방법  (0) 2015.03.25
[C++11] Thread Pool  (0) 2015.03.09
Class의 멤버함수 포인터  (0) 2015.03.09
ERROR LINK2019  (0) 2015.03.09
Posted by BeraPP
,

[C++11] Thread Pool

Study/C/C++ 2015. 3. 9. 15:48

 

※본 포스트는 Jakob's Devlog 블로그에서 퍼온 글입니다.

A Thread Pool with C++11

After showing a simple thread pool with Boost.Asio in the last post i’m going to have a look at doing the same thing with the threading facilities in C++11. The biggest difference is that we don’t have the Asio library so we have to reproduce the relevant functionality ourselves.
The declarations remain mostly the same except that the ThreadPool class doesn’t have the io_service members anymore but instead has a deque and synchronization primitives that we will use instead:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <thread>
#include <mutex>
#include <condition_variable>
 
class ThreadPool;
  
// our worker thread objects
class Worker {
public:
    Worker(ThreadPool &s) : pool(s) { }
    void operator()();
private:
    ThreadPool &pool;
};
  
// the actual thread pool
class ThreadPool {
public:
    ThreadPool(size_t);
    template<class F>
    void enqueue(F f);
    ~ThreadPool();
private:
    friend class Worker;
 
    // need to keep track of threads so we can join them
    std::vector< std::thread > workers;
 
    // the task queue
    std::deque< std::function<void()> > tasks;
 
    // synchronization
    std::mutex queue_mutex;
    std::condition_variable condition;
    bool stop;
};

Previously the Worker threads simply ran the io_service. Now they are where most of the magic happens. The most important part here is the condition_variable which is used to make the thread “sleep” when there are no jobs and wake it up when there are new jobs added to the queue. When calling condition_variable::wait with a lock the lock is released and the thread is suspended. When condition_variable::notify_one orcondition_variable::notify_all is called one or all waiting threads are woken up and reacquire the lock.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
void Worker::operator()()
{
    std::function<void()> task;
    while(true)
    {
        {   // acquire lock
            std::unique_lock<std::mutex>
                lock(pool.queue_mutex);
             
            // look for a work item
            while(!pool.stop && pool.tasks.empty())
            { // if there are none wait for notification
                pool.condition.wait(lock);
            }
 
            if(pool.stop) // exit if the pool is stopped
                return;
 
            // get the task from the queue
            task = pool.tasks.front();
            pool.tasks.pop_front();
 
        }   // release lock
 
        // execute the task
        task();
    }
}

Constructor and destructor mostly remain the same. The destructor now uses notify_allto make sure any suspended threads see that the stop flag is set.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// the constructor just launches some amount of workers
ThreadPool::ThreadPool(size_t threads)
    :   stop(false)
{
    for(size_t i = 0;i<threads;++i)
        workers.push_back(std::thread(Worker(*this)));
}
   
// the destructor joins all threads
ThreadPool::~ThreadPool()
{
    // stop all threads
    stop = true;
    condition.notify_all();
     
    // join them
    for(size_t i = 0;i<workers.size();++i)
        workers[i].join();
}

Finally the enqueue function just locks the queue, adds a task to it and wakes up one thread in case any thread was suspended.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// add new work item to the pool
template<class F>
void ThreadPool::enqueue(F f)
{
    { // acquire lock
        std::unique_lock<std::mutex> lock(queue_mutex);
         
        // add the task
        tasks.push_back(std::function<void()>(f));
    } // release lock
     
    // wake up one thread
    condition.notify_one();
}

The interface of the ThreadPool is unchanged, so the usage example from the last blog post still works. This version of the ThreadPool is slightly longer than the version with Boost.Asio but actually still relatively short for what it does and reduces the boost dependencies since we now don’t have to link boost libraries anymore.

This entry was posted in C++, Parallel Computing by JakobProgsch. Bookmark the permalink. 


원본: 


'Study > C/C++' 카테고리의 다른 글

explicit  (0) 2016.02.03
[boost] boost::asio::ip::tcp::socket에서 ip address 추출하는 방법  (0) 2015.03.25
[WinAPI] CriticalSection  (0) 2015.03.09
Class의 멤버함수 포인터  (0) 2015.03.09
ERROR LINK2019  (0) 2015.03.09
Posted by BeraPP
,



class B의 객체에서 class A의 멤버 함수를 함수 포인터를 이용해 실행시키는 예


'Study > C/C++' 카테고리의 다른 글

explicit  (0) 2016.02.03
[boost] boost::asio::ip::tcp::socket에서 ip address 추출하는 방법  (0) 2015.03.25
[WinAPI] CriticalSection  (0) 2015.03.09
[C++11] Thread Pool  (0) 2015.03.09
ERROR LINK2019  (0) 2015.03.09
Posted by BeraPP
,

ERROR LINK2019

Study/C/C++ 2015. 3. 9. 15:27

error link2019가 발생할 때의 원인과 해결법들을 간단하게 작성


1. lib파일을 추가하지 않았는지 확인!

프로젝트 속성(ALT + F7) -> 구현 속성 -> 링커 -> 입력에 추가 중속성 확인.

lib 파일은 다음과 같은 방법으로도 추가가 가능함

#pragma comment( lib, "lib" )


2. inline 함수 작성시 정의와 구현을 헤더와 구현파일에 나눠서 작성한 경우

inline 함수를 작성할 때 정의와 구현을 헤더와 cpp파일로 나눠서 작성하면 링크에러가 난다.

함수를 코드에 인라이닝 하는것은 inline 함수를 호출한 부분에 해당 함수의 정의를 넣는다는 뜻이다. 그런데 헤더에 함수명만 선언되어 있으면 함수 정의를 인라이닝 할 수 없기 때문에 링크에러가 생기게 된다.


3. mysql 연동시 생겼던 링크에러

32bit버전으로 구현중인데 mysql 64bit 버전을 설치하고 사용했더니 계속해서 link 에러가 발생했었다. 처음에 다운받을 때 제대로 확인 안하고 다운받았다가 이런 참사가 발생했다... 근데 64bit 버전을 써도 mysql관련 함수들을 inline함수로 구현하거나 헤더파일에 다 작성하면 또 실행이 되었다. 그래서 약 한달간을 제대로된 원인을 파악하지 못하고 고생을 한 적이 있었다. mysql 사용시 이유모를 link error가 발생한다면 위 사항을 점검해보길 추천


4. c, cpp 처럼 다른 확장자의 파일을 같은 프로젝터에 넣고 링크하지 말것


5. 함수를 정의만하고 구현하지 않았을 경우



나중에 또 이 문제가 발생하고 그 문제를 해결하게 되면 추가할 예정

'Study > C/C++' 카테고리의 다른 글

explicit  (0) 2016.02.03
[boost] boost::asio::ip::tcp::socket에서 ip address 추출하는 방법  (0) 2015.03.25
[WinAPI] CriticalSection  (0) 2015.03.09
[C++11] Thread Pool  (0) 2015.03.09
Class의 멤버함수 포인터  (0) 2015.03.09
Posted by BeraPP
,