http://en.wikipedia.org/wiki/Source_lines_of_code
sloccount
http://www.dwheeler.com/sloccount/
cmake 에 타겟 추가
# sloc
find_program(sloccount NAMES sloccount)
if(sloccount)
add_custom_target(sloc ${sloccount} ${CMAKE_SOURCE_DIR})
endif(sloccount)
헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤헤
# sloc
find_program(sloccount NAMES sloccount)
if(sloccount)
add_custom_target(sloc ${sloccount} ${CMAKE_SOURCE_DIR})
endif(sloccount)
아주 간단한 예제음.. 그런데 채널 이니 세마포어니 하는 것들도 보이네. 채널은 아예 프로듀서-컨슈머 모델인거 같고. 뭐가 어떤 용도로 쓰이는지 더 공부해야 하겠군. 사실 요 MVar 를 어떻게 써야 잘 쓰는건지 잘 안그려진다...펼쳐두기..
-- 희한하구먼. 문서상에도 나와있듯이 MVar 는 그냥 박스라고 생각하면
-- 된다. 다형성 타입이니 어떤 타입이건 담을수 있고 이 박스에서 값을
-- 꺼내거나 넣는 액션이 동기화 가능하다. 아래는 foo 쓰레드가 값을
-- 채우고 bar 쓰레드가 값을 꺼내가는 예제.
import Control.Concurrent
main = do
buf <- newEmptyMVar
foo <- forkIO $ threadFoo buf
bar <- forkIO $ threadBar buf
threadDelay 1000000000
threadFoo buf = do
threadDelay 500
putMVar buf 1
threadFoo buf
threadBar buf = do
v <- takeMVar buf
print v
threadBar buf
또다른 예제. () 를 넣어서 값 자체는 의미없이 이벤트처럼 써먹었다.펼쳐두기..
-- 음. MVar 를 이용해서 쓰레드가 끝나는 시점을 잡아봤다. 걍 간단히 원래
-- 받은 fun 을 forkIO 에 넘기기 전에 빈 Mvar 를 만들고 fun 실행후 이
-- MVar 에 () 을 채우는 중간 함수를 만들어서 이 중간 함수를 forkIO 에
-- 넘기도록 했다. haskell 문서상에는 비슷하지만 더 나은 예가 있던데
-- 예외는 아직 공부를 안해서 안 읽어봤다.
--
-- 아래코드는 당연히 걍 예제. thread 도 리턴 안하고 중간에 먹어버리는등
-- 문제 많은 코드. 음 common lisp 이라면 걍 멀티플 밸류로 넘겨버릴텐데
-- haskell 에서 튜플로 넘기면 받을때 귀찮아서 그냥 thread 는
-- 버려버렸다. common lisp 의 멀티플 밸류가 그립군?
import Control.Concurrent
-- 음 아래 guarded_fun 은 compose 나 closure 로 좀더 멋지게 작성이
-- 가능할거 같은데.. 좀 보기 흉하구먼.
fork fun = do
mvar <- newEmptyMVar
thread <- forkIO $ guarded_fun mvar
return mvar
where guarded_fun mvar = do
fun
putMVar mvar ()
join mvar = do
takeMVar mvar
print "joined"
main = do
mv <- fork thread
join mv
thread = do
threadDelay 5000000
print "done"
{-
두개의 쓰레드가 하나의 변수를 공유하는 예제를 만들어봤다.
공유한다는것 자체가 값이 변한다는 의미이니 펑셔널한것과는 거리가
멀고 따라서 모나드를 써야 하더라. IORef 가.. 일종의 변수..다른
언어들 처럼 값을 가지는 자리.. place holder 를 만들어주는
개념같구만. 이걸로 IORef a 타입의 값을 만들면 이 값을 통해 값을
읽거나, 바꾸거나 할수 있다.
아직 동기화 부분은 공부를 안해서 아래 코드는 상당히 엉성한데 (동기화
없고, 자식 thread 종료를 기다리는데 sleep 사용) 쓰레드간의 변수
공유라는 원래 목적엔 충분한 예제라고 생각 되는구만.
아.. 애초에 이걸 공부하게 된 이유는 haskell 에서 시그널 핸들러를 달고
있는 도중에 SIGINT 를 잡아도 main loop 에 멈추라는 플래그를 어떻게
전달을 해야 하나 고민을 하다가 작성하게 된것이다.
-}
import Data.IORef
import Control.Concurrent
-- 쓰레드? 두개를 까야지.
-- 두 쓰레드는 변수? var 를 공유하고
-- 한 쓰레드는 줄창 찍어대고
-- 한 쓰레드는 절절히 값을 바꿔보자.
-- 동기화는 아직 몰라서 안걸었삼.
main = do
var <- newIORef 0
foo <- forkIO (threadFoo var)
bar <- forkIO (threadBar var)
threadDelay 100000000 -- 음 낄낄. join 방법을 아직 몰라서..
threadFoo var = do
v <- readIORef var
print v
threadDelay 100
threadFoo var
-- 음 atomicModifyIORef 가 아주 편리해 보이는데 MVar 를 아직 모르니
-- 일단 넘어간다.
threadBar var = do
modifyIORef var (+1)
threadDelay 200
threadBar var
흠. 추가로 적어둔다.
건 위 코드로 테스트 후 만들어본 SIGINT 처리 예제
음. 사실 이런건 전역변수가 더 어울린다고 생각하는데
아직 잘 모르니 뭐..
-- 바쁘게 돌아가며 플래그를 확인하는 메인루프가 있고
-- SIGINT 떨어지면 플래그 값 바꿔서 메인루프 종료시키는
-- 간단한 예제
import System.Posix.Signals
import Data.IORef
import Control.Concurrent
loop stop = do
s <- readIORef stop
putStrLn "busy"
if s then return ()
else loop stop
sigint stop = do
print "SIGNAL"
writeIORef stop True
main = do
stop <- newIORef False
old_handler <- installHandler sigINT
(Catch $ sigint stop)
(Just fullSignalSet)
loop stop
(defun quick-switch-buffer ()
"f12 에 매핑을 했다면 C-u f12 를 눌러서 현재 버퍼를 기억해두고
f12 를 누르면 그 버퍼로 뿅"
(interactive)
(if current-prefix-arg
(setq *quick-switch-buffer* (current-buffer))
(switch-to-buffer *quick-switch-buffer*)))
(global-set-key [(f12)] 'quick-switch-buffer)
이런식으로..