Wednesday, November 18, 2015

파이썬 빌드(컴파일)

https://docs.python.org/2/extending/building.html

A distutils package contains a driver script, setup.py. This is a plain Python file, which, in the most simple case, could look like this:
from distutils.core import setup, Extension

module1 = Extension('demo',
                    sources = ['demo.c'])

setup (name = 'PackageName',
       version = '1.0',
       description = 'This is a demo package',
       ext_modules = [module1])

With this setup.py, and a file demo.c, running
python setup.py build

will compile demo.c, and produce an extension module named demo in the build directory. Depending on the system, the module file will end up in a subdirectory build/lib.system, and may have a name like demo.so ordemo.pyd.

Tuesday, November 10, 2015

ray tracing survey

ray tracing vs casting :
http://permadi.com/1996/05/ray-casting-tutorial-table-of-contents/

ray tracing :
https://www.cs.unc.edu/~rademach/xroads-RT/RTarticle.html

c++ example :
http://www.cosinekitty.com/raytrace/chapter05_cpp_code.html

ray tacing, ray packet, SAH(Surface Area Heuristic) :
http://www.cs.cmu.edu/afs/cs/academic/class/15869-f11/www/lectures/14_raytracing.pdf

아직 조사중.

Saturday, October 24, 2015

cmake + qt5 + vtk, for VS 2013 (community version)

1) Setup Qt5
In my case, I downloaded Qt5.4.2, qt-opensource-windows-x86-msvc2013_opengl-5.4.2.exe from here

2) Setup VTK
I haven't checked that QVtkWidget works for Qt5 at older VTK version,
but at least, it works for version 6.3.0.
After download source code, configure project for vs2013 with cmake.


After configure, check box for VTK_Qt, and click configure again.
If error message about "can't find package Qt5 ~~ ", then edit cmakelists.txt in VTK-6.3.0 as follows.


Just add the code on red line. After reedit, configure will work. Then generate project.

3) Compile VTK

4) Set automoc file.
-- I'll add about this topic. soon --

Friday, October 16, 2015

SEH error

GoogleTest, QVTKWidget에 멤버변수로 std::vector<~~>   를 여러개 추가하다가, SEH 에러 발생함. 아래 링크 참고로 원인 파악중.



http://stackoverflow.com/questions/13157671/seh-exception-with-code-0xc0000005-thrown-in-the-test-body

Monday, September 7, 2015

WaitForSingleObject not work

http://stackoverflow.com/questions/3552931/waitforsingleobject-not-work

auto reset or initially signalled.

Monday, August 10, 2015

how to solve visual studio profile error

When I tried cpu sampling test (performance, profiler) in visual studio 2013, window 8, there was error as follow.



'~~~' is not a valid process ID.

First time, I suspected vmware, but uninstall of it doens't work.
http://stackoverflow.com/questions/4524903/cant-start-visual-studio-profiler
https://connect.microsoft.com/VisualStudio/feedback/details/771324/vs2012-profiler-not-producing-any-call-tree-data-win-8-64

And finally, I find someone's solution.
http://www.symantec.com/connect/forums/cannot-profile-visual-studio-2010 



After setting registry and rebooting, sampling test work again!






Sunday, August 9, 2015

kd t ree - ray tracing

ray casting 연산을 bvh로만 하는건줄 알았떠니 그게 아니였다.

http://blog.frogslayer.com/kd-trees-for-faster-ray-tracing-with-triangles/

http://gamma.cs.unc.edu/graphicscourse/16_ray_tracing_2.pdf
: bvh, kdtree의 장단점 비교. Ray - AABB intersection

http://www.nvidia.com/content/nvision2008/tech_presentations/Game_Developer_Track/NVISION08-Interactive_Ray_Tracing.pdf
: nvida, implementation

http://www.cs.virginia.edu/~gfx/Courses/2010/IntroGraphics/Lectures/6-RayCasting.pdf

https://social.msdn.microsoft.com/Forums/en-US/85ebadf5-704e-4d1a-844a-be62a904e65a/functionality-needed-by-the-profiler-has-been-intercepted-by-another-application?forum=vstsprofiler

Sunday, July 26, 2015

Python class inherits new style, old style.

http://stackoverflow.com/questions/4015417/python-class-inherits-object http://stackoverflow.com/questions/54867/what-is-the-difference-between-old-style-and-new-style-classes-in-python
http://stackoverflow.com/questions/576169/understanding-python-super-with-init-methods

pyside + vtk

from PySide import QtCore, QtGui
from PySide.QtGui import QApplication
import vtk
from vtk.qt4.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
import sys


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(603, 553)
        self.centralWidget = QtGui.QWidget(MainWindow)
        self.gridlayout = QtGui.QGridLayout(self.centralWidget)
        self.vtkWidget = QVTKRenderWindowInteractor(self.centralWidget)
        self.gridlayout.addWidget(self.vtkWidget, 0, 0, 1, 1)
        MainWindow.setCentralWidget(self.centralWidget)


class SimpleView(QtGui.QMainWindow):
    def __init__(self, parent = None):
        QtGui.QMainWindow.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.ren = vtk.vtkRenderer()
        self.ui.vtkWidget.GetRenderWindow().AddRenderer(self.ren)
        self.iren = self.ui.vtkWidget.GetRenderWindow().GetInteractor()
 
        # Create source
        source = vtk.vtkSphereSource()
        source.SetCenter(0, 0, 0)
        source.SetRadius(5.0)
 
        # Create a mapper
        mapper = vtk.vtkPolyDataMapper()
        mapper.SetInputConnection(source.GetOutputPort())
 
        # Create an actor
        actor = vtk.vtkActor()
        actor.SetMapper(mapper)
 
        self.ren.AddActor(actor)
 
if __name__ == "__main__":
 
    app = QApplication(sys.argv)
    window = SimpleView()
    window.show()
    window.iren.Initialize() # Need this line to actually show the render inside Qt
    sys.exit(app.exec_())

how to setup vtk library on python

After download source code from here

1) Configure cmake including VTK_WRAP_PYTHON option. And then build it.


2) Compile the all source code. I suggest build it as release or optimized mode instead of debug mode.

3) Copy directory "Build\Wrapping\Python\vtk" (In my case "D:\vtk\VTK-6.1.0\bin\Wrapping\Python\vtk"), and paste the directory on "python\Lib\site-packages"

4) Copy all .dll files and .pyd files from "Build\bin\Release". Paste them on python\Lib\site-packages\vtk

Now, Setup is done. Let's practice with example. Copy the examples and paste, and run..


When you face the error, when using vtk on python

AttributeError: SetInput

You have to consider the replacement of setInput. Only thing you have to change is,.


SetInput -> SetInputConnection
Getoutput -> GetOutputPort

Sunday, July 19, 2015

pycharm, binary skeletons 추가

opencv 를 파이썬에 설치하고, pycharm에서 코드를 작성할 때, 아래와 같이 모듈이 인식되지 않는 경우가 있다.


Binary skeletons가 모듈을 인시갛지 못하는 경우 이런일이 발생하는데, 디렉토리를 사용자가 지정하는 방법은 아직 모르겠다.

임시방편으로 opencv\samples\python2 폴더의 아무 예제 코드를 실행하니, Binary skeletons에 바로 추가되는것을 확인했다.


Tuesday, July 14, 2015

static function, variable, member function

1) static function : 정적함수
참조 : http://stackoverflow.com/questions/558122/what-is-a-static-function
c문법. 함수 정의의 스코프를 해당 파일(.c, .cpp)에 제한한다. 파일을 다른표현으로 모듈이라고 부르기도 한다. 예를 들어 다음 파일들을 컴파일 할 경우,.

// a.c
void f(){
    printf("a.c : f()\n");
}
void func_a(){
    for(int i = 0; i < 4; i++)
        f();
}
// b.c
void f(){
    printf("b.c : f()\n");
}
void func_b(){
    for(int i = 0; i < 4; i++)
        f();
}

함수 void f()가 이미 선언된 함수를 제정의한다고 link time error를 일으킬 것이다. 이를 피하기 위해 static 함수를 선언하는것이 일반적이며, 다른 모듈(파일)에서 호출하도록 허용할 경우에는 일반함수로, 함수 원형 선언을 헤더파일에서 실시한다.
 
// a.h
#ifndef A_H_
#define A_H_  // inclusion guard

void func_a();

#endif
 
// b.h
#ifndef B_H_
#define B_H_

void func_b();

#endif
// a.c
static void f(){ // no more link time error
    printf("a.c : f()\n");
}
void func_a(){
    for(int i = 0; i < 4; i++)
        f();
}
// b.c
static void f(){
    printf("b.c : f()\n");
}
void func_b(){
    for(int i = 0; i < 4; i++)
        f();
}
 
// main.c
#include "a.h"
#include "b.h"
void main(){
    func_a();
    func_b();
}

inclusion guard에 대한 설명은 다음기회에.

2) static variable
 지역변수는 함수의 함수가 종료(return)될 때 파괴된다. 그러나 정적변수(static variable)은 함수가 종료되어도 파괴되지 않고 그 값을 유지해, 다음 호출에서 활용할 수 있다.
 google style guide에서는 전역변수와 더불어 정적변수를 예외적인 경우를 제외하고는 기본적으로 금지하고 있다.#
 본인도 메모리 할당, 해제에 의한 성능저하 방지를 위해, 프로파일에 근거해 병목지점인 경우에만 한해서 써본것 외에 많이쓰지 않으며, 이마저도 멀티쓰레드 코딩으로 변경하는 과정에서 다시 병목지점이 되는 문제가 발생해, 결국 정적변수를 없에고, 다른 방법으로 문제를 처리한 경험이 있다.

3) static member function, static member variable
정적변수, 정적함수와는 전혀 다른 문법이다. 싱글턴 패턴구현에도 사용되는 문법.

http://soen.kr/lecture/ccpp/cpp3/27-3-2.htm
http://soen.kr/lecture/ccpp/cpp3/27-3-3.htm

인스턴스의 구현 없이 호출, 초기화가 가능한 장점이 있으며, 각 인스턴스에서도 접근이 가능하다.
예를 들면,
 a) 생성자를 private으로 접근을 제한한 다음, 정의된 정적 멤버 함수를 거쳐서만 생성자가 호출되게 하므로써 싱글턴 패턴이 구현 가능하며,
 b) 또는 생성자 및 파괴자의 매 호출마다 정적 변수 number_of_instance 를 업데이트해, 이를 관리하는식으로 활용할 수 도 있다.

Sunday, July 12, 2015

python 스터디

스터디 및 정리중
1] 파이썬 튜토리얼
1-1) https://docs.python.org/2.7/
1-2) https://wikidocs.net/
* 지하철에서 모바일로 예습하기에 딱 좋다. 내용이 지루해서 컴퓨터앞에서 집중해서 읽기는 힘들었다. 그래도 알긴 해야함.
1-3) https://www.youtube.com/watch?v=Xy903pH7BLA
* 참조2 강의는 정말 맘에든다.
* '일일이 작성하는건 인간이 할짓이 아니다.'라는 표현이 정말 웃긴다.
* 우리 주변엔 컴퓨터의 노예인 코더가 너무 많기때문에 ㅋㅋ
* line 앞에 #을 붙이면 주석
* line 앞에 """을 붙여도 주석. 함수 바로 아래에 쓰면 docstring기능을 한다.
* type casting : 형변환. str(i)
* object, property & method
* print( '{} year, {} day printed'.format(year, day) )
* print( '{1} year, {2} day printed'.format(year, day) )
* 아래와 같이, 출력형태 지정 가능
    print( '{1:%d} year, {2:%x} day, {3, %.2f} sec printed'.format(year, day, float_sec) )
* years_to_print = [ str(y) for y in range(1800, 2014,1) ]
* print(", ".join(years_to_print)) # list의 사이에 본 문자열을 끼워 넣는다.
* years_to_print = [ str(y) for y in range(1800, 2014,1) if y%3 == 0]
* 파일 입출력. open(), write(), close()

1-4) 파이썬 어렵게 배우기 :  http://learnpythonthehardway.org/book/intro.html
1-5) 파이썬 디자인 패턴 : https://www.youtube.com/watch?v=0vJJlVBVTFg
* ppt : http://cdn.oreillystatic.com/en/assets/1/event/45/Practical%20Python%20Patterns%20Presentation.pdf


2] 파이썬특징
2-1) https://ko.wikipedia.org/wiki/파이썬
파이썬에는 「건전지 포함("Battery Included")」이란 기본 개념이 있어 프로그래머가 바로 사용할 수 있는 라이브러리와 통합 환경이 이미 배포판과 함께 제공된다. 이로써 파이썬의 표준 라이브러리는 매우 충실하다. 여기에는 정규표현식을 비롯해 운영 체제의 시스템 호출이나 처리, 직렬화, HTTP ,FTP 등의 각종 통신 프로토콜, 전자 메일이나 CSV 파일의 처리, 데이터베이스 접속, 그래픽 사용자 인터페이스, HTML, 파이썬 코드 구문 분석 도구 등을 포함한다.

 파이썬을 강점은 생산성, 가독성에 있다. 파이썬을 파이썬스럽게 하려면, 스타일 가이드를 잘 따라야한다.

2-3) python의 포인터 개념은?
* 파이썬은 기본적으로 call by reference 개념으로, 포인터가 없다.
* ids는 포인터 개념이 아니다. ids(10)과 a = 10, ids(a) 를 비교해봐라. 똑같다.
* http://www.quora.com/How-can-we-implement-data-structures-like-doubly-linked-lists-in-Python-where-there-is-no-concept-of-pointers
* call by reference이므로 대처 가능하다.

2-4) List comprehension
https://docs.python.org/2/tutorial/datastructures.html
* 리스트 문법 덕분에, multi input(parameter)뿐만 아니라 multi output 도 간단하게 구현 가능하다. c++에서는 리턴타입을 정의해야 하므로, struct, class로 묶거나, reference 파라미터로 받아야 했던걸 상기하하면, 더 직관적이다.

2-5) 파이썬은 동적 언어다.
* 같은 클래스의 오브젝트임에도 필드 변수가 서로 다를 수가 있다. 오브젝트에 필드변수를 추가하는게 가능하다.  - c++같은경우 있을수 없는 일이다.
* 이러한 특징이 유연한 프로그래밍이 가능하게 해준다. - 같은 기능을 구현할때 c++의 경우 부모클래스에 추상함수를 선언하고, 자식함수에서 부모를 상속받는 과정을 거쳐야한다. 같은 기능의 구현이 100% 가능하지만, 더 많이 손이 간다.

2-6) 어느 파라미터 인자인지 명시하여, 순서가 바뀌어도 문제 없이 호출 가능

2-7) 파이썬은 덕타이핑 언어다.
* https://ko.wikipedia.org/wiki/덕_타이핑
* 파이썬에서는 덕타이핑으로써 인터페이스가 암시되어 있다. 덕분에 훨씬 짧은 코드로 구현이 가능하다.

3] 파이썬 문법
3-1) 리스트
* 이중 리스트
* 슬라이싱
* append : elment 한개 확장
* extend : 리스트 + 리스트 확장
* reverse : 순서 반전.
* index : 일치하는 엘리먼트를 찾아서 인덱스 반환.
* sort : 정렬.

3-2) 딕셔너리 (dictionary)
* {Key1:Value1, Key2:Value2, Key3:Value3 ...}

3-3) 연산자 오버로딩
__lt__ : less then
__le__ : less or equal then

3-4) map
* map(함수, 인자리스트) : 리스트 각 인자에 대한 호출 자동화.
* 예제코드 : map(lamda x : x*x, [1, 2, 3, 4])

3-5) 파이썬의 __metaclass__와 inheritance의 차이.
 http://stackoverflow.com/questions/17801344/python-understanding-metaclass-and-inheritance

3-6) __dict__
* read only로 클래스의 정보를 꺼내보임.
* 파이썬이 스크립트 언어니까 __buitlins__.__dict__["exit"]() 같은 호출도 가능하다

4] 기타
4-1) IPython
* ref : http://www.slideshare.net/TaeYoungLee1/20150306-ipython
* 대화형 컴퓨팅으로 분석 프로그래밍에 적합
* 운영체제의 쉘 파일 시스템과 통합
* 웹 기반의 대화형 노트북 지원. 수식, 표, 그림 표현가능


setup pyside at pycharm

1) File - Settings



2) Type 'project interprete'. Click '+'. 



3) Install PySide.


4) Now, It works.


import sys
from PySide import QtGui
app = QtGui.QApplication(sys.argv)
win = QtGui.QWidget()
win.resize(320, 240)
win.setWindowTitle("Hello, World!")
win.show()
sys.exit(app.exec_())

vtk

 vtk는 3D 컴퓨터 그래픽, 모델링, 영상처리, 과학 및 정보의 영상화(visualization)를 위한 c++ 오픈소스 툴킷으로 python, java도 지원한다. 알고리즘을 구현하는 과정에서 console 출력밖에 마땅한 방법이 없어 고생하던 차에 오프소스에서 많이 사용하는 것을 보고 관심을 가지게 되었다.

 The Visualization Toolkit (VTK) is an open-source, freely available software system for 3D computer graphics, modeling, image processing, volume rendering, scientific visualization, and information visualization. VTK also includes ancillary support for 3D interaction widgets, two- and three-dimensional annotation, and parallel computing. At its core, VTK is implemented as a C++ toolkit, requiring users to build applications by combining various objects into an application. The system also supports automated wrapping of the C++ core into Python, Java, and Tcl, so VTK applications may also be written using these interpreted programming languages.

 적당한 도구를 발견하기 전까지는 OpenGL을 사용해 직접 그렸지만, 화려한 게임을 만들려는 것도 아닌데 너무 많은 속성지정이 필요하고, 직접 구현해야 하는 기능이 많은 탓에 3d 출력 구현에만 너무 많은 시간이 낭비되는 경험을 하기도 했다.  vtk는 패턴화된 파이프라인으로 통해 쉽게 3D 오브젝트 생성(출력)과 속성부여(색, 투명)가 가능하게 해준다.

vtk 설치법
 c++의 경우 대부분의 오픈소스가 그렇듯이, 소스코드를 다운로드 받고, 소스코드에 대해 camke를 이용해 프로젝트를 생성해서 직접 바이너리 파일(.lib, .dll 파일)을 컴파일하면 된다.

vtk 이해
 직관적인 vtk 파이프라인 구조 때문에, 아무리 설명을 읽어봤자, 사실 직접 예제를 컴파일해가면서 몇번 따라하는것만 못하다. 그럼에도 불구하고 궂이 파이라인 개념에 대한 설명을 읽자면, 내가 본 자료 중에선 아래 링크가 가장 쉽게 이해가 되었다.


원 출처에선, 색칠된 박스를 직접 클릭해 자세한 설명을 읽을 수 있다. 예제와 함께 파이프라인을 비교해보자.

 우선 프로젝트를 만들어야 한다.
 예제코드 밑의 'here to download cylinder'에서 소스코드를 다운받고, cmake를 이용해 프로젝트를 생성하면 된다. 소스코드를 읽어보면 다음과 같다.

vtkCylinderSource 객체로부터 실린더에 해당하는 형상정보(버텍스, 폴리곤등)을 가져온다.
실린더 형상의 속성을 default값으로부터 변경할 수 있다.
해당 예제에서는 Filter가 생략되고 바로 source로부터 Mapper로 바로 파이프가 연결되었다. 마지막으로 mapper는 actor로 연결된다.

 Renderer 상에 등록되는 actor는 말그대로 배우처럼 화면에 출력되는 object가 된다. 동일한 mapper를 참조하는 여러개의 actor를 생성하여 renderer에 등록(소스코드 addactor)하면 동일한 형상의 actor 여러개를 동시에 화면에 띄우게 가능하고, 이미 등록되어 화면에 출력중인 실린더actor에 대해 setmapper함수를 다시 호출하여 박스로 형상을 바꾸는것도 가능하다.
http://www.vtk.org/Wiki/VTK/Examples/Cxx/에서 필요한 예제들을 몇번 따라하고 읽어보면, 이해하는데는 큰 어려움은 없다.

 vtkSmartPointer가 이해가 안간다면 smart pointer에 대해 찾아보면 된다. 결론부터 말하자면 new, delete 를 자동화해 메모리 누수를 예방한다.

 actor는 강력한 기능이지만 그만큼 코스트가 많이 요구된다. 예를 들어 만개의 sampling 점집합을  만개의 radius 1짜리 spherer actor로 출력하는것보단 만개의 point로 이루어진 1개의 actor로 출력하는 쪽이 훨씬 합리적이다.

 나는 개인적으로 QVtkWidget내의 renderer에 actor들을 등록해 출력하는쪽을 선호한다. Qt가 제공하는 UI 추가가 훨씬 쉽기 때문에.

Tuesday, July 7, 2015

eng,c++> launching multiple console

It is being edited

#include  <stdio.h>
#include  <iostream>
#include  <windows.h>
#include  <string>

int main(int argc, char* argv[]){
 SetConsoleTitle(argv[0]);
 std::string slot_name = "\\\\.\\mailslot\\" + std::string(argv[0]);
 char buff[100];
 HANDLE h_mailslot = CreateMailslot(slot_name.c_str(), 0, MAILSLOT_WAIT_FOREVER, NULL);
 if(h_mailslot == INVALID_HANDLE_VALUE){
  printf("Unable to create mailslot!\n");
  throw 1;
 }
 while(1){
  DWORD n_byte;
  if(!ReadFile(h_mailslot, buff, sizeof(buff), &n_byte, NULL))
   break;
   buff[n_byte / sizeof(char)] = 0;
   if(strcmp(buff, "exit")==0)
       break;
   printf("%s", buff);
 }
 CloseHandle(h_mailslot);
 return 0;
}
console.exe

#include  <stdio.h>
#include  <iostream>
#include  <windows.h>
#include  <process.h>
#include  <direct.h>

std::string getExePath(){
 char buffer[MAX_PATH];
 GetModuleFileName(NULL, buffer, MAX_PATH);
 std::string str(buffer);
 std::string::size_type pos = str.find_last_of("\\/");
 return str.substr(0, pos);
}

class Console {
public:
 Console(std::string title = "debug"){
  STARTUPINFO info = { sizeof(info) };
  PROCESS_INFORMATION process_info;
  std::string filepath = getExePath() + "\\console.exe";
  if(!CreateProcess(filepath.c_str(), const_cast <char *>(title.c_str()), NULL, NULL, false, CREATE_NEW_CONSOLE, NULL, NULL, &info, &process_info)){
   printf("CreateProcess() failure.\n");
   throw 1;
  }
  h_cmd_process = process_info.hProcess;
  Sleep(1000); // waiting for process
  std::string slot_name = "\\\\.\\mailslot\\" + title;
  h_mailslot = CreateFile(slot_name.c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  if(h_mailslot == INVALID_HANDLE_VALUE){
   printf("Unable to create mailslot %d\n", GetLastError());
   throw 1;
  }
 }
 void print(const std::string& message){
  DWORD exitCode;
  GetExitCodeProcess(h_cmd_process, &exitCode);
  if(exitCode != STILL_ACTIVE) {
   //task exited with code exitCode
  }
  DWORD n_byte;
  if(!WriteFile(h_mailslot, message.c_str(), message.length()*sizeof(char), &n_byte, NULL)){
  }
 }
 ~Console(){
  print("exit");
  //TerminateProcess(h_cmd_process, 0);
  CloseHandle(h_mailslot);
 }
private:
 HANDLE h_cmd_process;
 HANDLE h_mailslot; 
};

void main(){
    Console console;
    for(int i = 0; i  < 10; i++){
        std::string message = "hello hell? " + std::to_string((_ULonglong)i) + "\n";
        console.print(message);
    }
    getchar();
}

client.exe

Class Consoles launch process "console.exe" when it is created. It send string by mailslot(msdn). The "client.exe" should be launched as administrator.

kor,c++> multi thread programming (windows)

다음은 멀티스레드로 두 함수의 무한루프를 동시에 실행하는 예제 코드이다.

/*
multi thread example
*/
#include "stdafx.h"
#include <vector>
#include <windows.h>
#include <process .h> // _beginthread, _endthread
#include <conio .h> // _kbihit
class C {
public:
 void update(){
  v_.push_back(0);
  printf("v.size() = %d\n", v_.size());
 }
private:
 std::vector<int> v_;
};

unsigned int __stdcall t1(void*arg){
 C* c = (C*)arg;
 while(true){
  c->update();
 }
 return 0;
}
unsigned int __stdcall t2(void*arg){
 C* c = (C*)arg;
 while(true){
  c->update();
 }
 return 0;
}

int main() {
 C c;
 HANDLE h_t1 = (HANDLE)_beginthreadex(0, 0, &t1, &c, 0, 0);
 HANDLE h_t2 = (HANDLE)_beginthreadex(0, 0, &t2, &c, 0, 0);
 while(true){
  if(_kbhit())
   exit(0);
 }
 return 0;
}
예제 1-1

동시에 실행되는 함수 t1, t2에서 같은 인스턴스 c의 멤버 v_에 접근을 하는데도 고의로 스레드 보호를 하지 않았다. 그 결과 아래와 같이 에러가 발생한다. 


여러 개의 스레드가 공유 데이터를 사용할 때를 가르켜 race condition, 경쟁 상태, 경쟁 조건이라고 부른다. #
이와같은 런타임에러는 불규칙하게 발생하기 때문에 발견하기도 힘들고, 충돌 원인을 찾기도 힘들다. 그러므로 미리 잘 설계하는게 중요하다.
스레드 보호를 위해서 아래와 같이 mutex 변수를 선언하고 동기화를 수행하였다.

#include "stdafx.h"
#include <vector>
#include <windows.h>
#include <process.h> // _beginthread, _endthread
#include <conio.h> // _kbihit

class C {
public:
 C() : mutex_(CreateMutex(0, 0, 0)){
 }

~C(){
 CloseHandle(mutex_);
}

void update(){
 lock();
 v_.push_back(0);
 int d = v_.size();
 unlock();
 printf("v.size() = %d\n", d);
}

private:
 void lock(){
  WaitForSingleObject(mutex_, INFINITE);
 }

void unlock(){
  ReleaseMutex(mutex_);
 }
 HANDLE mutex_;
 std::vector<int> v_;
};

unsigned int __stdcall t1(void*arg){
 C* c = (C*)arg;
 while(true){
  c->update();
 }
 return 0;
}

unsigned int __stdcall t2(void*arg){
 C* c = (C*)arg;
 while(true){
  c->update();
 }
 return 0;
}

int main() {
 C c;
 HANDLE h_t1 = (HANDLE)_beginthreadex(0, 0, &t1, &c, 0, 0);
 HANDLE h_t2 = (HANDLE)_beginthreadex(0, 0, &t2, &c, 0, 0);
 while(true){
  if(_kbhit())
   exit(0);
 }
 return 0;
}
예제 1-2

WaitForSingleObject(mutex_, INFINITE) 함수가 호출되면, ReleaseMutex(mutex_)가 호출되기 전까지 다른 쓰레드에서는 WaitForSingleObject(mutex_, INFINITE) 함수가 완료되지 않는다. 만약 ReleaseMutex(mutex_)가 적절히 호출되지 못하는 코드를 구현하면, 시스템은 교착상태에 빠질수 있으므로 주의해야한다.

다른 예제로 넘어가, 접근자를 구현해보자.

#include "stdafx.h"
#include <vector>
#include <windows.h>
#include <process.h> // _beginthread, _endthread
#include <conio.h> // _kbihit

class C {
public:
 C() : v_(0), mutex_(CreateMutex(0, 0, 0)){

 }
 ~C(){
  CloseHandle(mutex_);
 }
 void set(int v){
  v_ = v;
 }
 int get()const{
  return v_;
 }
private:
 void lock(){
  WaitForSingleObject(mutex_, INFINITE);
 }
 void unlock(){
  ReleaseMutex(mutex_);
 }
 HANDLE mutex_;
 int v_;
};

unsigned int __stdcall t1(void*arg){
 C* c = (C*)arg;
 int t = 0;
 while(true){
  c->set(t++);
 }
 return 0;
}
unsigned int __stdcall t2(void*arg){
 C* c = (C*)arg;
 while(true){
  printf("v = %d\n", c->get());
 }
 return 0;
}
int main() {
 C c;
 HANDLE h_t1 = (HANDLE)_beginthreadex(0, 0, &t1, &c, 0, 0);
 HANDLE h_t2 = (HANDLE)_beginthreadex(0, 0, &t2, &c, 0, 0);
 while(true){
  if(_kbhit())
   exit(0);
 }
 return 0;
}
예제 2-1

예제 2-1은 get,set 접근자에 lock, unlock을 적용하기 전이다. 무서운점은 분명 충돌이 발생할 코드임에도, 3,40분 실행으로는 충돌이 발생하지 않았다는거다. 예제1-1에 비해 연산시간이 짧은 관계로 확률이 낮기 때문이다. 이런종류의 런타임 버그가 프로그램 전체의 신뢰성을 좀먹는 가장 무서운 버그다. ("내가 할땐 잘됬어! 다른데 니가 건드린게 문제있는거 아니야?")

본론으로 돌아와, get, set함수에 lock unlock을 선언해보자. 아래 주석과 같은 에러가 발생할 것이다.

#include "stdafx.h"
#include <vector>
#include <windows.h>
#include <process.h> // _beginthread, _endthread
#include <conio.h> // _kbihit

class C {
public:
        C() : v_(0), mutex_(CreateMutex(0, 0, 0)){

        }
        ~C(){
                CloseHandle(mutex_);
        }
        void set(int v){
                lock();
                v_ = v;
                unlock();
        }
        int get()const{
                // error C2662: 'void C::lock(void)' : cannot convert 'this' pointer from 'const C' to 'C &'
                lock();
                int v = v_;
                // error C2662: 'void C::unlock(void)' : cannot convert 'this' pointer from 'const C' to 'C &'
                unlock();
                return v;
        }
private:
        void lock(){
                WaitForSingleObject(mutex_, INFINITE);
        }
        void unlock(){
                ReleaseMutex(mutex_);
        }
        HANDLE mutex_;
        int v_;
};

unsigned int __stdcall t1(void*arg){
        C* c = (C*)arg;
        int t = 0;
        while(true){
                c->set(t++);
        }
        return 0;
}
unsigned int __stdcall t2(void*arg){
        C* c = (C*)arg;
        while(true){
                printf("v = %d\n", c->get());
        }
        return 0;
}
int main() {
        C c;
        HANDLE h_t1 = (HANDLE)_beginthreadex(0, 0, &t1, &c, 0, 0);
        HANDLE h_t2 = (HANDLE)_beginthreadex(0, 0, &t2, &c, 0, 0);
        while(true){
                if(_kbhit())
                        exit(0);
        }
        return 0;
}

일반적으로 접근자 get 함수는 객체의 상태를 바꾸지 않는다는 의미로 상수 멤버 함수로 선언하는게 맞다.# 그럼에도 스레드 보호를 위한 함수 lock, unlock은 상수형 함수가 아니므로 에러가 발생하는것이다.
lock, unlock을 상수 멤버 함수로 선언해도 같은 에러가 lock, unlock의 선언에서 발생한다. WaitForSingleObject, ReleaseMutex 함수가 멤버변수 mutex_를 변경하는 함수이기 때문에.

이러한 문제를 우회하는 방법은 두가지 있다.

1. get함수를 일반 멤버함수로 바꾸는 방법 - 가능하면 추천지 않는다.
2. mutex를 mutable 멤버변수로 변경하는 방법.

Q : Should mutexes be mutable? If I want to keep the public method interface as const as possible, but make the object thread safe, should I use mutable mutexes? In general, is this good style, or should a non-const method interface be preferred? Please justify your view.
A : Basically using const methods with mutable mutexes is a good idea (don't return references by the way, make sure to return by value), at least to indicate they do not modify the object. Mutexes should not be const, it would be a shameless lie to define lock/unlock methods as const... Actually this (and memoization) are the only fair uses I see of the mutable keyword.

 그렇다. mutable 문법을 쓰는게 정당해보이는 보기드문, 유일한 경우가 mutex 정도이니 변형없는 상수형 함수라 거짓말치는 mutable을 문법을 쓴다해서 부끄러워할 필요는 없다.

2번째 방법으로 문제를 해결하면 다음과 같다.
class C {
public:
 C() : v_(0), mutex_(CreateMutex(0, 0, 0)){

 }
 ~C(){
  CloseHandle(mutex_);
 }
 void set(int v){
  lock();
  v_ = v;
  unlock();
 }
 int get()const{
  lock();
  int v = v_;
  unlock();
  return v;
 }
private:
 void lock()const {
  // 상수형 멤버함수로 선언하는데, 더이상 mutex_가 문제되지 않는다.
  WaitForSingleObject(mutex_, INFINITE);
 }
 void unlock()const{
  ReleaseMutex(mutex_);
 }
 mutable HANDLE mutex_;
 int v_;
};

kor> blog spot SyntaxHighligter 사용법

출처 : http://stackoverflow.com/questions/10335463/how-to-setup-syntax-highlighter-on-blogger

1) 설치법
1-1) 기존 블로거 template부터 백업.
대시보드 - 템플릿 - HTML 편집




1-2) </b:skin> 앞에, 다음 링크로부터 복사한 소스코드 붙여넣기.


1-3) 아래 코드를 </head> 앞에 붙여넣기
단, 원문과 달리 shTheme를 사용하기위해서 css 및 js 코드를 alexgorbatchev로 부터 가져왔다.  google 저장소에서는 style 디렉토리를 찾지 못했기 때문.
shThemeEmacs.css 대신 다른 테마를 찾아 취향대로 적용할 수 있다.


<!-- Syntax Highlighter Additions START -->
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shCore.css' rel='stylesheet' type='text/css'/>
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shThemeEmacs.css' rel='stylesheet' type='text/css'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js' type='text/javascript'/>
 
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushAS3.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushBash.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushColdFusion.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCSharp.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCpp.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCss.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushDelphi.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushDiff.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushErlang.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushGroovy.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJScript.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJava.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJavaFX.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPerl.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPhp.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPlain.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPowerShell.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPython.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushRuby.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushScala.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushSql.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushVb.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js' type='text/javascript'/>
<!-- Syntax Highlighter Additions END -->

1-4)</body> 앞에 아래 소스코드 붙여넣기.

<script language='javascript'>
dp.SyntaxHighlighter.BloggerMode();
dp.SyntaxHighlighter.HighlightAll('code');
</script>

1-5) 템플릿 저장

2) 사용법
 html 편집모드에서 아래와 같이 name="code" class=속성 을 지정하고 코드를 작성하면 된다. gutter:false는 줄번호 생략하는것을 뜻한다. &lt; 는 < 꺽쇠기호를 뜻하며, 꺽쇠기호를 치환하지 않고 입력한다면 이사람 과 같이 #include< 내용이 소스코드 마지막에 </ 로 반복 출력되는 에러, 버그를 겪을 것이다.

<pre name="code" class="brush:cpp gutter:false">
#include &lt;stdio.h>
void main(){
    printf("hello hell??\n");
}
</pre>
cpp
#include <stdio.h>
void main(){
    printf("hello hell??\n");
}
출력 결과

 단, 게시 후에만 SyntaxHighligter가 지원되며 미리보기 모드에서는 지원되지 않는다.