<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4377783716972458045</id><updated>2011-11-28T09:11:11.956+09:00</updated><category term='C++'/><category term='xml'/><category term='multiplexed I/O'/><category term='Unicode'/><category term='socket'/><category term='protocol buffer'/><category term='Collective Intelligence'/><category term='tool'/><category term='python'/><category term='Programming Pearls'/><category term='mod_python'/><category term='epoll'/><category term='pattern'/><category term='fonts'/><category term='Misc'/><category term='network'/><category term='environment'/><category term='algorithm'/><category term='django'/><category term='thread'/><category term='management'/><category term='Programming'/><category term='google'/><category term='HTML5'/><title type='text'>Programmer's Diary</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default?start-index=101&amp;max-results=100'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>131</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-6617078692165309905</id><published>2011-06-24T11:15:00.001+09:00</published><updated>2011-06-24T11:16:45.430+09:00</updated><title type='text'>Recording Desktop at Ubuntu</title><content type='html'>Very simple.&lt;br /&gt;&lt;br /&gt;Record with gtk-RecordMyDeskTop. Outfile format will be .ogv&lt;br /&gt;&lt;br /&gt;To convert ogv to avi, &lt;br /&gt;&lt;br /&gt;&gt; mencoder -idx out.ogv -ovc lavc -oac mp3lame -o out.avi&lt;br /&gt;&lt;br /&gt;Done.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-6617078692165309905?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/6617078692165309905/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2011/06/recording-desktop-at-ubuntu.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/6617078692165309905'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/6617078692165309905'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2011/06/recording-desktop-at-ubuntu.html' title='Recording Desktop at Ubuntu'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-1292132752914012691</id><published>2011-06-13T23:26:00.003+09:00</published><updated>2011-06-14T00:05:15.739+09:00</updated><title type='text'>C++: Building custom vector class.</title><content type='html'>&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Making custom container class with iterator would be a good example for C++ beginner.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Vector.h&lt;br /&gt;&lt;br /&gt;&lt;div style="background:black url(http://www.pulsarwallpapers.com/data/media/22/Leopard%20Space%20Desktop.jpg);color:#ffffff;font-family:monospace"&gt;&lt;br /&gt;&lt;span style="color:#ff40ff"&gt;#ifndef VECTOR_H&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#ff40ff"&gt;#define VECTOR_H&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#ff40ff"&gt;#include &lt;/span&gt;&lt;span style="color:#ff6060"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#ff40ff"&gt;#include &lt;/span&gt;&lt;span style="color:#ff6060"&gt;&amp;quot;VectorIterator.h&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#00ff00"&gt;class&lt;/span&gt;&amp;nbsp;Vector {&lt;br /&gt;&lt;span style="color:#ffff00"&gt;public&lt;/span&gt;:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#00ff00"&gt;typedef&lt;/span&gt;&amp;nbsp;VectorIterator iterator;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Vector(&lt;span style="color:#00ff00"&gt;int&lt;/span&gt;&amp;nbsp;size) { data_.resize(size); }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#00ff00"&gt;int&lt;/span&gt;&amp;nbsp;size() &lt;span style="color:#00ff00"&gt;const&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#00ff00"&gt;void&lt;/span&gt;&amp;nbsp;push_back(&lt;span style="color:#00ff00"&gt;const&lt;/span&gt;&amp;nbsp;&lt;span style="color:#00ff00"&gt;int&lt;/span&gt;&amp;nbsp;val);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;VectorIterator begin();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;VectorIterator end();&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#00ff00"&gt;int&lt;/span&gt;&amp;amp; &lt;span style="color:#ffff00"&gt;operator&lt;/span&gt;[](&lt;span style="color:#00ff00"&gt;const&lt;/span&gt;&amp;nbsp;&lt;span style="color:#00ff00"&gt;int&lt;/span&gt;&amp;amp; idx);&lt;br /&gt;&lt;span style="color:#ffff00"&gt;private&lt;/span&gt;:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::vector&amp;lt;&lt;span style="color:#00ff00"&gt;int&lt;/span&gt;&amp;gt; data_;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#00ff00"&gt;inline&lt;/span&gt;&amp;nbsp;&lt;span style="color:#00ff00"&gt;int&lt;/span&gt;&amp;nbsp;&amp;amp;&lt;br /&gt;Vector::&lt;span style="color:#ffff00"&gt;operator&lt;/span&gt;[](&lt;span style="color:#00ff00"&gt;const&lt;/span&gt;&amp;nbsp;&lt;span style="color:#00ff00"&gt;int&lt;/span&gt;&amp;amp; idx) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffff00"&gt;return&lt;/span&gt;&amp;nbsp;data_[idx];&lt;br /&gt;}&lt;br /&gt;&lt;span style="color:#00ff00"&gt;inline&lt;/span&gt;&amp;nbsp;&lt;span style="color:#00ff00"&gt;int&lt;/span&gt;&lt;br /&gt;Vector::size() &lt;span style="color:#00ff00"&gt;const&lt;/span&gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffff00"&gt;return&lt;/span&gt;&amp;nbsp;data_.size();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#00ff00"&gt;inline&lt;/span&gt;&amp;nbsp;&lt;span style="color:#00ff00"&gt;void&lt;/span&gt;&lt;br /&gt;Vector::push_back(&lt;span style="color:#00ff00"&gt;const&lt;/span&gt;&amp;nbsp;&lt;span style="color:#00ff00"&gt;int&lt;/span&gt;&amp;nbsp;val) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;data_.push_back(val);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffff00"&gt;return&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#ff40ff"&gt;#endif&lt;/span&gt;&amp;nbsp;&lt;span style="color:#8080ff"&gt;/*&lt;/span&gt;&lt;span style="color:#8080ff"&gt;&amp;nbsp;VECTOR_H &lt;/span&gt;&lt;span style="color:#8080ff"&gt;*/&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Vector.cpp&lt;br /&gt;&lt;br /&gt;&lt;div style="background:#000000 url(http://www.pulsarwallpapers.com/data/media/22/Leopard%20Space%20Desktop.jpg);color:#ffffff;font-family:monospace"&gt;&lt;br /&gt;&lt;span style="color:#ff40ff"&gt;#include &lt;/span&gt;&lt;span style="color:#ff6060"&gt;&amp;quot;Vector.h&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;VectorIterator&lt;br /&gt;Vector::begin() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffff00"&gt;return&lt;/span&gt;&amp;nbsp;VectorIterator(&amp;amp;data_);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;VectorIterator&lt;br /&gt;Vector::end() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;VectorIterator vec(&amp;amp;data_);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;vec.setIndex(data_.size());&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffff00"&gt;return&lt;/span&gt;&amp;nbsp;vec;&lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;VectorIterator.h&lt;br /&gt;&lt;br /&gt;&lt;div style="background:black url(http://www.pulsarwallpapers.com/data/media/22/Leopard%20Space%20Desktop.jpg);color:#ffffff;font-family:monospace"&gt;&lt;br /&gt;&lt;span style="color:#ff40ff"&gt;#ifndef VECTORITERATOR_H&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#ff40ff"&gt;#define VECTORITERATOR_H&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#ff40ff"&gt;#include &lt;/span&gt;&lt;span style="color:#ff6060"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#00ff00"&gt;class&lt;/span&gt;&amp;nbsp;VectorIterator {&lt;br /&gt;&lt;span style="color:#ffff00"&gt;public&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;VectorIterator();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;VectorIterator(std::vector&amp;lt;&lt;span style="color:#00ff00"&gt;int&lt;/span&gt;&amp;gt; * data);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#00ff00"&gt;void&lt;/span&gt;&amp;nbsp;setIndex(&lt;span style="color:#00ff00"&gt;int&lt;/span&gt;&amp;nbsp;v);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#00ff00"&gt;int&lt;/span&gt;&amp;nbsp;&lt;span style="color:#ffff00"&gt;operator&lt;/span&gt;*();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#00ff00"&gt;int&lt;/span&gt;&amp;nbsp;&lt;span style="color:#ffff00"&gt;operator&lt;/span&gt;++();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#00ff00"&gt;bool&lt;/span&gt;&amp;nbsp;&lt;span style="color:#ffff00"&gt;operator&lt;/span&gt;==(&lt;span style="color:#00ff00"&gt;const&lt;/span&gt;&amp;nbsp;VectorIterator&amp;amp; rhs) &lt;span style="color:#00ff00"&gt;const&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#00ff00"&gt;bool&lt;/span&gt;&amp;nbsp;&lt;span style="color:#ffff00"&gt;operator&lt;/span&gt;!=(&lt;span style="color:#00ff00"&gt;const&lt;/span&gt;&amp;nbsp;VectorIterator&amp;amp; rhs) &lt;span style="color:#00ff00"&gt;const&lt;/span&gt;;&lt;br /&gt;&lt;span style="color:#ffff00"&gt;private&lt;/span&gt;:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::vector&amp;lt;&lt;span style="color:#00ff00"&gt;int&lt;/span&gt;&amp;gt;* pvec_;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#00ff00"&gt;int&lt;/span&gt;&amp;nbsp;index_;&lt;br /&gt;}; &lt;br /&gt;&lt;br /&gt;&lt;span style="color:#00ff00"&gt;inline&lt;/span&gt;&amp;nbsp;&lt;span style="color:#00ff00"&gt;int&lt;/span&gt;&lt;br /&gt;VectorIterator::&lt;span style="color:#ffff00"&gt;operator&lt;/span&gt;*()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffff00"&gt;return&lt;/span&gt;&amp;nbsp;(*pvec_)[index_];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#00ff00"&gt;inline&lt;/span&gt;&amp;nbsp;&lt;span style="color:#00ff00"&gt;int&lt;/span&gt;&lt;br /&gt;VectorIterator::&lt;span style="color:#ffff00"&gt;operator&lt;/span&gt;++()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;index_++;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffff00"&gt;return&lt;/span&gt;&amp;nbsp;(*pvec_)[index_];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#00ff00"&gt;inline&lt;/span&gt;&amp;nbsp;&lt;span style="color:#00ff00"&gt;bool&lt;/span&gt;&lt;br /&gt;VectorIterator::&lt;span style="color:#ffff00"&gt;operator&lt;/span&gt;==(&lt;span style="color:#00ff00"&gt;const&lt;/span&gt;&amp;nbsp;VectorIterator&amp;amp; rhs) &lt;span style="color:#00ff00"&gt;const&lt;/span&gt;&lt;br /&gt;{   &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffff00"&gt;return&lt;/span&gt;&amp;nbsp;(pvec_ == rhs.pvec_ &amp;amp;&amp;amp; index_ == rhs.index_);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#00ff00"&gt;inline&lt;/span&gt;&amp;nbsp;&lt;span style="color:#00ff00"&gt;bool&lt;/span&gt;&lt;br /&gt;VectorIterator::&lt;span style="color:#ffff00"&gt;operator&lt;/span&gt;!=(&lt;span style="color:#00ff00"&gt;const&lt;/span&gt;&amp;nbsp;VectorIterator&amp;amp; rhs) &lt;span style="color:#00ff00"&gt;const&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffff00"&gt;return&lt;/span&gt;&amp;nbsp;!(*&lt;span style="color:#ffff00"&gt;this&lt;/span&gt;&amp;nbsp;== rhs);&lt;br /&gt;}&lt;br /&gt;&lt;span style="color:#ff40ff"&gt;#endif&lt;/span&gt;&amp;nbsp;&lt;span style="color:#8080ff"&gt;/*&lt;/span&gt;&lt;span style="color:#8080ff"&gt;&amp;nbsp;VECTORITERATOR_H &lt;/span&gt;&lt;span style="color:#8080ff"&gt;*/&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;VectorIterator.cpp&lt;br /&gt;&lt;br /&gt;&lt;div style="background:black url(http://www.pulsarwallpapers.com/data/media/22/Leopard%20Space%20Desktop.jpg);color:#ffffff;font-family:monospace"&gt;&lt;br /&gt;&lt;span style="color:#ff40ff"&gt;#include &lt;/span&gt;&lt;span style="color:#ff6060"&gt;&amp;quot;VectorIterator.h&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#00ff00"&gt;void&lt;/span&gt;&lt;br /&gt;VectorIterator::setIndex(&lt;span style="color:#00ff00"&gt;int&lt;/span&gt;&amp;nbsp;v) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;index_ = v;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffff00"&gt;return&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;VectorIterator::VectorIterator()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;: pvec_(&lt;span style="color:#ff6060"&gt;NULL&lt;/span&gt;), index_(&lt;span style="color:#ff6060"&gt;0&lt;/span&gt;) {}&lt;br /&gt;&lt;br /&gt;VectorIterator::VectorIterator(std::vector&amp;lt;&lt;span style="color:#00ff00"&gt;int&lt;/span&gt;&amp;gt; * data) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;: pvec_(data), index_(&lt;span style="color:#ff6060"&gt;0&lt;/span&gt;) {}&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;main.cpp&lt;br /&gt;&lt;br /&gt;&lt;div style="background:#000000 url(http://www.pulsarwallpapers.com/data/media/22/Leopard%20Space%20Desktop.jpg);color=#ffffff;font-family:monospace"&gt;&lt;br /&gt;&lt;span style="color:#ff40ff"&gt;#include &lt;/span&gt;&lt;span style="color:#ff6060"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#ff40ff"&gt;#include &lt;/span&gt;&lt;span style="color:#ff6060"&gt;&amp;quot;Vector.h&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#00ff00"&gt;int&lt;/span&gt;&amp;nbsp;main()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#00ff00"&gt;int&lt;/span&gt;&amp;nbsp;size = &lt;span style="color:#ff6060"&gt;10&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Vector vec(size);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffff00"&gt;for&lt;/span&gt;&amp;nbsp;(&lt;span style="color:#00ff00"&gt;int&lt;/span&gt;&amp;nbsp;i = &lt;span style="color:#ff6060"&gt;0&lt;/span&gt;; i &amp;lt; vec.size(); i++)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;vec[i] = &lt;span style="color:#ff6060"&gt;2&lt;/span&gt;&amp;nbsp;* i;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffff00"&gt;for&lt;/span&gt;&amp;nbsp;(Vector::iterator iter = vec.begin();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;iter != vec.end(); ++iter)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::cout &amp;lt;&amp;lt; *iter &amp;lt;&amp;lt; std::endl;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffff00"&gt;return&lt;/span&gt;&amp;nbsp;&lt;span style="color:#ff6060"&gt;0&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-1292132752914012691?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/1292132752914012691/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2011/06/c-building-custom-vector-class.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/1292132752914012691'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/1292132752914012691'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2011/06/c-building-custom-vector-class.html' title='C++: Building custom vector class.'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-3997044221940489911</id><published>2011-06-09T18:14:00.003+09:00</published><updated>2011-06-09T18:25:39.440+09:00</updated><title type='text'>making google preview</title><content type='html'>&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;With phantomjs, I made a simple search preview like Google's preview.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;img src="http://4.bp.blogspot.com/-Y7m1KpPqRyU/TfCQZlzX6pI/AAAAAAAAAJ8/TqZCV_KghKE/s400/pv.png" style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 266px;" border="0" alt="" id="BLOGGER_PHOTO_ID_5616147504649726610" /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;When user input query, thumbnail for each search result is gathered simultaneously. This works with render function of phantomjs(webkit based script binary). The image it made is saved with hashed url as a filename so that it would not render twice. And it also highlight with red box where the query appears in the page(You can see little tiny red bordered box in the thumbnail above, right?). Though it consumes lots of system resources, it works.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-3997044221940489911?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/3997044221940489911/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2011/06/making-google-preview.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/3997044221940489911'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/3997044221940489911'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2011/06/making-google-preview.html' title='making google preview'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-Y7m1KpPqRyU/TfCQZlzX6pI/AAAAAAAAAJ8/TqZCV_KghKE/s72-c/pv.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-5985329995300309584</id><published>2011-03-04T00:07:00.002+09:00</published><updated>2011-03-04T00:22:13.459+09:00</updated><title type='text'>C++ pointer, reference - **, *&amp;, &amp;&amp;, &amp;*</title><content type='html'>&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Let's think about pointer and reference with - &amp;amp;&amp;amp;, &amp;amp;*, ** and *&amp;amp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;int &amp;amp;&amp;a;&lt;br /&gt;ILLEGAL : '&amp;amp;&amp;amp;' is a comparison syntax, not a pointer nor reference thing. Pass.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;int &amp;amp;*a;&lt;br /&gt;ILLEGAL : (pointer-to-reference) Can't declare a pointer to int&amp;amp;. Reference is another name of an object(you can't set a pointer to a 'name').&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;int **a;&lt;br /&gt;pointer-to-pointer : You can use&lt;br /&gt;value(**a), pointer address(*a) and pointer's pointer address(a).&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;int *&amp;a;&lt;br /&gt;reference-to-pointer : You can use&lt;br /&gt;value(*a), pointer address(a) and pointer's pointer address(&amp;amp;a).&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Get confused :) ?&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-5985329995300309584?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/5985329995300309584/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2011/03/c-pointer-reference.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/5985329995300309584'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/5985329995300309584'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2011/03/c-pointer-reference.html' title='C++ pointer, reference - **, *&amp;, &amp;&amp;, &amp;*'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-4756327635757469387</id><published>2011-02-10T14:29:00.008+09:00</published><updated>2011-02-23T00:44:36.997+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>C++ Exception</title><content type='html'>&lt;blockquote&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;/blockquote&gt;Exception is consist of detection and handling.&lt;br /&gt;&lt;br /&gt;When an exception happens, program stops, finds where to handle, handles exception, and resumes from where it handled an eception.&lt;br /&gt;&lt;br /&gt;Class, integer or string can be an exception object to be thrown.&lt;br /&gt;&lt;br /&gt;Throwing an exception is done by&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;&lt;blockquote&gt;&lt;span style="color:#3333ff;"&gt;throw exceptionObject;&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;/span&gt;&lt;br /&gt;Try always goes with catch.&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;&lt;blockquote&gt;&lt;span style="color:#3366ff;"&gt;try {&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;throw "happened!";&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;catch (const char *msg) {&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;catch (...) &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;// handles all exceptions.&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Exception can be sent to upper routine after handling.&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;&lt;blockquote&gt;&lt;span style="color:#3366ff;"&gt;catch (...) {&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;// handles exception&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;...&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;throw; // propagates again for the other handler &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If no handler found, program ends with terminate().&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Thinks&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;When a class constructor fails, only exception can make it known to the program.&lt;br /&gt;&lt;br /&gt;Use of exception reduces 'if ... else ...' statements.&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;&lt;blockquote&gt;&lt;span style="color:#3366ff;"&gt;// Before,&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;if (condition) {&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;// do something &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;} &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;else {&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;// handle by itself &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;// After,&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;check_condition(); // raise exception. &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;// do something&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;/span&gt;&lt;br /&gt;Level of exception handler in the program is where it knows the exception and the way to handle it.(In other words, it's good to propagate an exception to the upper routine when it's not adequate to handle it there.)&lt;br /&gt;&lt;br /&gt;Exception is different from hardware exception like seg-fault. That means there's 'throw' codes in the program.&lt;br /&gt;&lt;br /&gt;This kind of handling code of resource releasing is not that good.&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;&lt;blockquote&gt;&lt;p&gt;&lt;span style="color:#3366ff;"&gt;// not a good example.&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;try {&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;// alloc something.&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#3366ff;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;catch (...) {&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;// release them.&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;throw;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;/span&gt;&lt;br /&gt;Instead, resource alloc, release routine is good to be in the constructor, destructor code of the class("Resource aquisition is initialization" - Bjarne Stroustrup). "Because &lt;strong&gt;exception handling guarantees to call all destructors of local variables&lt;/strong&gt;".&lt;br /&gt;&lt;br /&gt;Standard exceptions.&lt;div&gt;C++ offers 'exception' basic class. This class has a virtual function 'what()' which returns const char * so, we can know what's going on during an exception with this message(throw() means this function will not throw an exception).&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;class exception {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;public:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;virtual const char * what() const throw();&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;So if your code has a catch statement like below, it catches all kinds of standard exception which inherits from the exception class.&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;catch (const std::exception &amp;amp;ex) {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;std::cout &amp;lt;&amp;lt; ex.what() &amp;lt;&amp;lt; std::endl;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;strong&gt;Notes&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;Auto pointer.&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;&lt;blockquote&gt;&lt;span style="color:#3366ff;"&gt;#include &amp;lt;memory&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;...&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;auto_ptr&lt;aclass&gt; p(new AClass); // will be released automatically.&lt;br /&gt;&lt;/aclass&gt;&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-4756327635757469387?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/4756327635757469387/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2011/02/c-exception.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/4756327635757469387'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/4756327635757469387'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2011/02/c-exception.html' title='C++ Exception'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-8762251428687127078</id><published>2011-01-12T10:09:00.000+09:00</published><updated>2011-01-12T10:10:33.459+09:00</updated><title type='text'>c++ iostream 간단 요약</title><content type='html'>간단하게 정리해놨네. Good.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;http://goo.gl/uh36O&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-8762251428687127078?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/8762251428687127078/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2011/01/c-iostream.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/8762251428687127078'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/8762251428687127078'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2011/01/c-iostream.html' title='c++ iostream 간단 요약'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-909695548981195727</id><published>2010-12-28T15:16:00.001+09:00</published><updated>2010-12-28T15:17:46.034+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Python egg</title><content type='html'>Very good explanation on Python egg package&lt;br /&gt;&lt;ul&gt;&lt;li&gt;http://mrtopf.de/blog/en/a-small-introduction-to-python-eggs/&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-909695548981195727?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/909695548981195727/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2010/12/python-egg.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/909695548981195727'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/909695548981195727'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2010/12/python-egg.html' title='Python egg'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-7317045869301526711</id><published>2010-12-23T14:39:00.002+09:00</published><updated>2010-12-23T14:47:04.997+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='pattern'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>Strategy pattern implementation using member function pointer.</title><content type='html'>Strategy pattern is used when there are various ways to solve one problem. Normally each algorithm to solve problem is implemented as a class. And those classes are inherited from base class. However, it's also possible to implement those pattern using member function pointers though it looks a bit quirky like &lt;strong&gt;(instace.*instance.functionPointer)(...)&lt;/strong&gt;. :)&lt;br /&gt;&lt;br /&gt;&lt;font face="monospace"&gt;&lt;br /&gt;&lt;font color="#0000c0"&gt;&lt;b&gt;#include &lt;/b&gt;&lt;/font&gt;&lt;font color="#c000c0"&gt;&lt;b&gt;&amp;lt;iostream&amp;gt;&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#008000"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/font&gt;&amp;nbsp;Class {&lt;br /&gt;&lt;font color="#804000"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#008000"&gt;&lt;b&gt;typedef&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#008000"&gt;&lt;b&gt;enum&lt;/b&gt;&lt;/font&gt;&amp;nbsp;OPERATION {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SUM = &lt;font color="#c000c0"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MUL&lt;br /&gt;&amp;nbsp;&amp;nbsp;} operation;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;Class();&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#008000"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;func(&lt;font color="#008000"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;a, &lt;font color="#008000"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;b, operation op);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#008000"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;(Class::*fp[&lt;font color="#c000c0"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/font&gt;])(&lt;font color="#008000"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;a, &lt;font color="#008000"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;b);&lt;br /&gt;&lt;font color="#804000"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt;:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#008000"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;sum(&lt;font color="#008000"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;a, &lt;font color="#008000"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;b);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#008000"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;mul(&lt;font color="#008000"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;a, &lt;font color="#008000"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;b);&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;Class::Class()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;fp[SUM] = &amp;amp;Class::sum;&lt;br /&gt;&amp;nbsp;&amp;nbsp;fp[MUL] = &amp;amp;Class::mul;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;font color="#008000"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;Class::func(&lt;font color="#008000"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;a, &lt;font color="#008000"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;b, Class::operation op)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#804000"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;(&lt;font color="#804000"&gt;&lt;b&gt;this&lt;/b&gt;&lt;/font&gt;-&amp;gt;*fp[op])(a, b);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;font color="#008000"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;Class::sum(&lt;font color="#008000"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;a, &lt;font color="#008000"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;b)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#804000"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;a + b;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;font color="#008000"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;Class::mul(&lt;font color="#008000"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;a, &lt;font color="#008000"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;b)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#804000"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;a * b;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;font color="#008000"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;main()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;Class c;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;std::cout &amp;lt;&amp;lt; c.func(&lt;font color="#c000c0"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/font&gt;, &lt;font color="#c000c0"&gt;&lt;b&gt;4&lt;/b&gt;&lt;/font&gt;, Class::SUM) &amp;lt;&amp;lt; std::endl;&lt;br /&gt;&amp;nbsp;&amp;nbsp;std::cout &amp;lt;&amp;lt; (c.*c.fp[Class::MUL])(&lt;font color="#c000c0"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/font&gt;, &lt;font color="#c000c0"&gt;&lt;b&gt;4&lt;/b&gt;&lt;/font&gt;) &amp;lt;&amp;lt; std::endl;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#804000"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#c000c0"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;/font&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-7317045869301526711?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/7317045869301526711/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2010/12/strategy-pattern-implementation-using.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/7317045869301526711'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/7317045869301526711'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2010/12/strategy-pattern-implementation-using.html' title='Strategy pattern implementation using member function pointer.'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-2764725900654917558</id><published>2010-11-23T14:41:00.003+09:00</published><updated>2010-11-23T14:48:23.678+09:00</updated><title type='text'>번역 완료 - HTML5 활용</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_HMeTW73pU4s/TOtVdpbljhI/AAAAAAAAAJo/aqjKGilHDGM/s1600/html5unr.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 100px; height: 119px;" src="http://1.bp.blogspot.com/_HMeTW73pU4s/TOtVdpbljhI/AAAAAAAAAJo/aqjKGilHDGM/s400/html5unr.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5542617734235655698" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;휴~ 번역 언제 끝나나 싶더니 벌써 예판 시작했네요. 이번 역서&lt;a href="http://www.yes24.com/24/goods/4401059?scode=032&amp;srank=1"&gt;&lt;/a&gt;는 한참 회자되고 있는 HTML5 내용입니다. 구글의 개발자 어드버킷 마크 필그림의 책이구요. 얇은 책 내용안에 HTML5에 관해 알아야할 부분들을 조목조목 설명하고 있습니다. 자칫 일부 기능만 보다가 놓치기 쉬운 큰 그림에 대해 잘 설명해주소 있고, 기존 HTML의 역사라던가 어떻게 발전해왔는지 등에 대해서도 설명하고 있어서 꼭 한번 읽어볼만한 책입니다.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-2764725900654917558?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/2764725900654917558/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2010/11/html5.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/2764725900654917558'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/2764725900654917558'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2010/11/html5.html' title='번역 완료 - HTML5 활용'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_HMeTW73pU4s/TOtVdpbljhI/AAAAAAAAAJo/aqjKGilHDGM/s72-c/html5unr.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-8448251464989063364</id><published>2010-07-02T16:40:00.002+09:00</published><updated>2010-09-03T17:15:45.237+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='HTML5'/><title type='text'>Very good HTML5 tutorials.</title><content type='html'>Awesome!&lt;br /&gt;&lt;br /&gt;http://www.html5rocks.com/&lt;br /&gt;&lt;br /&gt;http://www.chromeexperiments.com/&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-8448251464989063364?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/8448251464989063364/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2010/07/very-good-html5-tutorials.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/8448251464989063364'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/8448251464989063364'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2010/07/very-good-html5-tutorials.html' title='Very good HTML5 tutorials.'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-4731281757116132686</id><published>2010-07-01T18:54:00.008+09:00</published><updated>2010-07-02T22:27:26.452+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='protocol buffer'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Google Protocol Buffer 구글의 프로토콜 버퍼</title><content type='html'>&lt;div&gt;Sometimes when we make data structure and use it for file i/o or network, writing manipulating functions is bothersome. Moreover it's a kind of stress when we have to use it over different environment or implementation. People tried to solve this matter for a long time(Maybe you've heard about XDR before). By the way, Google also faced the same and they were using what so called Google Protocol Buffer. It generates classes to manipulate our data structure expressed with .proto file for c++, python and java.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;가끔식 특정 데이터 포맷 만들어 파일에 읽고 쓰거나 네트웍으로 전송할 일이 있을 때 이를 조작하는 함수들을 구현하고 테스트 하는 부분이 성가실 때가 있다. 특히 다른 환경(OS, 서버)이나 구현(언어)에서 동일하게 동작하는지 체크하는 과정은 시간을 잡아먹는다. 그래서 XDR같은 걸로 해결해 보려는 시도가 이전에 있었는데, 알고보니 구글에서도 비슷한 고민을 한거 같다. 얘네들은 구글 프로토콜 버퍼를 사용하는데, .proto 파일로 데이터 구조를 만들고 protoc로 컴파일 하면 c++, 파이썬, 자바로 관련 조작함수나 클래스를 생성해준다. 일종의 코드 제네레이터처럼.&lt;/div&gt;&lt;br /&gt;&lt;div bg="" text="#ffffff"&gt;&lt;span style="font-family:monospace;"&gt;                                           &lt;br /&gt;package contacts;                                                                               &lt;br /&gt;                                                                                           &lt;br /&gt;message Person {                                        &lt;br /&gt;required int32 id = 1;                                      &lt;br /&gt;required string name = 2;                            &lt;br /&gt;optional string email = 3;                    &lt;br /&gt;}                                                          &lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;This is a simple .proto file. We can compile this with protoc to generate code. Let me try to get a c++ code to manipulate this data format.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;간단한 .proto 파일인데, protoc로 컴파일 할 수 있다. C++코드를 만들어보자.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&gt; protoc contact.proto --cpp_out=.&lt;/div&gt;&lt;div&gt;&gt; ls&lt;/div&gt;&lt;div&gt;contact.pb  contact.pb.cc  contact.pb.h contact.proto&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Functions are defined in the header file above and you can also check it at the site. Ok. Now it's the time to use it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;조작함수는 구글 사이트나 contact.pb.h 헤더 파일을 보면 된다. 자, 그럼 한번 써볼까.&lt;/div&gt;&lt;br /&gt;&lt;div bg="" text="#ffffff"&gt;&lt;span style="font-family:monospace;"&gt;&lt;br /&gt;&lt;span style="color:#0000c0;"&gt;&lt;b&gt;#include &lt;/b&gt;&lt;/span&gt;&lt;span style="color:#c000c0;"&gt;&lt;b&gt;&amp;lt;iostream&amp;gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#0000c0;"&gt;&lt;b&gt;#include &lt;/b&gt;&lt;/span&gt;&lt;span style="color:#c000c0;"&gt;&lt;b&gt;&amp;lt;fstream&amp;gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#0000c0;"&gt;&lt;b&gt;#include &lt;/b&gt;&lt;/span&gt;&lt;span style="color:#c000c0;"&gt;&lt;b&gt;"contact.pb.h"&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#804000;"&gt;&lt;b&gt;using&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#008000;"&gt;&lt;b&gt;namespace&lt;/b&gt;&lt;/span&gt; std;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#008000;"&gt;&lt;b&gt;static&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#008000;"&gt;&lt;b&gt;const&lt;/b&gt;&lt;/span&gt; string datafile = &lt;span style="color:#c000c0;"&gt;&lt;b&gt;"contact.pb"&lt;/b&gt;&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#008000;"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/span&gt; pbWrite(&lt;span style="color:#008000;"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/span&gt; id, string name, string email)&lt;br /&gt;{&lt;br /&gt;Person person;&lt;br /&gt;person.set_id(id);&lt;br /&gt;person.set_name(name);&lt;br /&gt;person.set_email(email);&lt;br /&gt;&lt;br /&gt;fstream out(datafile.c_str(), ios::out|ios::binary|ios::trunc);&lt;br /&gt;person.SerializeToOstream(&amp;amp;out);&lt;br /&gt;out.close();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#008000;"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/span&gt; pbRead(Person &amp;amp;p)&lt;br /&gt;{&lt;br /&gt;fstream in(datafile.c_str(), ios::in|ios::binary);&lt;br /&gt;&lt;span style="color:#804000;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt;(!p.ParseFromIstream(&amp;amp;in)) {&lt;br /&gt;  fprintf(&lt;span style="color:#c000c0;"&gt;&lt;b&gt;stderr&lt;/b&gt;&lt;/span&gt;, &lt;span style="color:#c000c0;"&gt;&lt;b&gt;"ERROR : Read Person from input stream&lt;/b&gt;&lt;/span&gt;&lt;span style="color:#c00000;"&gt;&lt;b&gt;\n&lt;/b&gt;&lt;/span&gt;&lt;span style="color:#c000c0;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;);&lt;br /&gt;  &lt;span style="color:#804000;"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/span&gt; -&lt;span style="color:#c000c0;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;cout &amp;lt;&amp;lt; p.DebugString();&lt;br /&gt;&lt;span style="color:#008080;"&gt;&lt;b&gt;/*&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#008080;"&gt;&lt;b&gt;  cout &amp;lt;&amp;lt; "id : " &amp;lt;&amp;lt; p.id() &amp;lt;&amp;lt; endl;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#008080;"&gt;&lt;b&gt;  cout &amp;lt;&amp;lt; "name : " &amp;lt;&amp;lt; p.name() &amp;lt;&amp;lt; endl;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#008080;"&gt;&lt;b&gt;  cout &amp;lt;&amp;lt; "email : " &amp;lt;&amp;lt; p.email() &amp;lt;&amp;lt; endl;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#008080;"&gt;&lt;b&gt;  &lt;/b&gt;&lt;/span&gt;&lt;span style="color:#008080;"&gt;&lt;b&gt;*/&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;in.close();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#008000;"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/span&gt; main()&lt;br /&gt;{&lt;br /&gt;GOOGLE_PROTOBUF_VERIFY_VERSION;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#008080;"&gt;&lt;b&gt;//pbWrite(12345, "Dustin Hyun", "dongseok.hyun@emailaddress.com");&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Person p;&lt;br /&gt;(&lt;span style="color:#008000;"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/span&gt;) pbRead(p);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#804000;"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#c000c0;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div bg="" text="#ffffff"&gt;&lt;span style="font-family:monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div bg="" text="#ffffff"&gt;&lt;span class="Apple-style-span"   style="font-family:monospace;font-size:100%;"&gt;&lt;span class="Apple-style-span"  style="font-size:13px;"&gt;For version check, you should use macro GOOGLE_PROTOBUF_VERIFY_VERSION. Each member has get/set functions(see the code above). And you can serialize the data with SerializeToOstream() and parse from the file or stream with ParseFromIstream(). So cool and easy. This also works on the other implementation using python or java exactly the same way. It also support convenient functions like DebugString().&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div bg="" text="#ffffff"  style="color:#000000;"&gt;&lt;span class="Apple-style-span"   style="font-family:monospace;font-size:100%;"&gt;&lt;span class="Apple-style-span"  style="font-size:13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div bg="" text="#ffffff"&gt;&lt;span class="Apple-style-span"   style="font-family:monospace;font-size:100%;"&gt;&lt;span class="Apple-style-span"  style="font-size:13px;"&gt;구글의 프로토콜 버퍼 버전 체크를 위해 GOOGLE_PROTOBUF_VERIFY_VERSION 매크로를 사용하고, 각 멤버들은 get/set 함수들이 있어 접근할 수 있다. 중요한것은,. 이런 데이터를 SerializeToOstream(), ParseFromIstream() 함수로 파일에 저장하거나 불러올 수 있고, 네트웍상에도 전달할 수 있다는 것. 겁나 편할 뿐 아니라 파이썬, 자바등 다른 언어로 구현된 코드들과도 호환되니 좋을 수밖에. C++로 서버를 구현하고 파이썬 qt로 짠 어플리케이션 클라이언트로 받아야 하는 상황이라면 완전 편하게 사용할 수 있다. DebugString() 같은 편리한 함수도 만들어주니 써보자 ^^;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div bg="" text="#ffffff"&gt;&lt;span class="Apple-style-span"   style="font-family:monospace;font-size:100%;"&gt;&lt;span class="Apple-style-span"  style="font-size:13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div bg="" text="#ffffff"&gt;&lt;span class="Apple-style-span"   style="font-family:monospace;font-size:100%;"&gt;&lt;span class="Apple-style-span"  style="font-size:13px;"&gt;Ps. don't forget to write -pthread &lt;path&gt; 컴파일시 인스톨한 라이브러리 경로 넣어주는 거 잊지 말자.&lt;/path&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-4731281757116132686?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/4731281757116132686/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2010/07/google-protocol-buffer.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/4731281757116132686'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/4731281757116132686'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2010/07/google-protocol-buffer.html' title='Google Protocol Buffer 구글의 프로토콜 버퍼'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-2465477637913832388</id><published>2010-04-07T17:34:00.003+09:00</published><updated>2010-07-02T16:42:49.809+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>Time Conversion</title><content type='html'>&lt;ul&gt;&lt;li&gt;Get struct timeval&lt;br /&gt;&lt;b&gt;gettimeofday()&lt;/b&gt;&lt;/li&gt;&lt;li&gt;Get struct timespec&lt;br /&gt;&lt;b&gt;clock_gettime()&lt;/b&gt;&lt;/li&gt;&lt;li&gt;Time string -&gt; struct tm&lt;br /&gt;&lt;b&gt;strptime()&lt;/b&gt;&lt;/li&gt;&lt;li&gt;struct tm -&gt; time string&lt;br /&gt;&lt;b&gt;strftime()&lt;/b&gt;&lt;/li&gt;&lt;li&gt;tm -&gt; unix time time_t&lt;br /&gt;&lt;b&gt;mktime()&lt;/b&gt;&lt;/li&gt;&lt;li&gt;Others.&lt;br /&gt;Refer time.h&lt;br /&gt;(asctime() , clock() , difftime() , gmtime() , localtime() , mktime() , strftime() , strptime() , time() , utime())&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-2465477637913832388?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/2465477637913832388/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2010/04/time-conversion.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/2465477637913832388'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/2465477637913832388'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2010/04/time-conversion.html' title='Time Conversion'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-5106925432091074099</id><published>2010-02-16T10:27:00.006+09:00</published><updated>2010-12-23T14:38:14.696+09:00</updated><title type='text'>Function Object</title><content type='html'>In C++, we normally make class instance and call a method of the instance. However, there's a way to call class instance itself as a function like below.&lt;br /&gt;&lt;br /&gt;&lt;font face="monospace"&gt; &lt;font color="#a52a2a"&gt;&amp;nbsp;1 &lt;/font&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;iostream&amp;gt;&lt;/font&gt;&lt;br&gt; &lt;font color="#a52a2a"&gt;&amp;nbsp;2 &lt;/font&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;functional&amp;gt;&lt;/font&gt;&lt;br&gt; &lt;font color="#a52a2a"&gt;&amp;nbsp;3 &lt;/font&gt;&lt;br&gt; &lt;font color="#a52a2a"&gt;&amp;nbsp;4 &lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;using&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;namespace&lt;/b&gt;&lt;/font&gt;&amp;nbsp;std;&lt;br&gt; &lt;font color="#a52a2a"&gt;&amp;nbsp;5 &lt;/font&gt;&lt;br&gt; &lt;font color="#a52a2a"&gt;&amp;nbsp;6 &lt;/font&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/font&gt;&amp;nbsp;Sample&lt;br&gt; &lt;font color="#a52a2a"&gt;&amp;nbsp;7 &lt;/font&gt;{&lt;br&gt; &lt;font color="#a52a2a"&gt;&amp;nbsp;8 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;:&lt;br&gt; &lt;font color="#a52a2a"&gt;&amp;nbsp;9 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;operator&lt;/b&gt;&lt;/font&gt;() (&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;a, &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;b) &lt;font color="#2e8b57"&gt;&lt;b&gt;const&lt;/b&gt;&lt;/font&gt;&amp;nbsp;{&lt;br&gt; &lt;font color="#a52a2a"&gt;10 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;a + b;&lt;br&gt; &lt;font color="#a52a2a"&gt;11 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt; &lt;font color="#a52a2a"&gt;12 &lt;/font&gt;};&lt;br&gt; &lt;font color="#a52a2a"&gt;13 &lt;/font&gt;&lt;br&gt; &lt;font color="#a52a2a"&gt;14 &lt;/font&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;main()&lt;br&gt; &lt;font color="#a52a2a"&gt;15 &lt;/font&gt;{&lt;br&gt; &lt;font color="#a52a2a"&gt;16 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Sample s;&lt;br&gt; &lt;font color="#a52a2a"&gt;17 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cout &amp;lt;&amp;lt; s(&lt;font color="#ff00ff"&gt;1&lt;/font&gt;, &lt;font color="#ff00ff"&gt;2&lt;/font&gt;) &amp;lt;&amp;lt; endl;&lt;br&gt; &lt;font color="#a52a2a"&gt;18 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#ff00ff"&gt;0&lt;/font&gt;;&lt;br&gt; &lt;font color="#a52a2a"&gt;19 &lt;/font&gt;}&lt;br&gt; &lt;/font&gt;&lt;br /&gt;&lt;br /&gt;You can set input arguments information and return type like line 9 above. Function object is processed as an inline function, so it's fast than normal function call. And it is also useful when you want to set a status related to a certain function cause it's class so it can keep a value as a member.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-5106925432091074099?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/5106925432091074099/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2010/02/function-object.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/5106925432091074099'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/5106925432091074099'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2010/02/function-object.html' title='Function Object'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-1795283934234131705</id><published>2010-01-19T17:56:00.002+09:00</published><updated>2010-01-19T18:03:18.783+09:00</updated><title type='text'>What right people are heading for in this generation, 'Open'</title><content type='html'>As time goes by, the world offers more things to see, to know and to feel. If we are right people for this generation, we can feel that the world is going to that trend, 'sharing more and more'.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://googleblog.blogspot.com/2009/12/meaning-of-open.html"&gt;The meaning of Open&lt;/a&gt; posted on Google blog tells exactly what I was heading for(&lt;a href="http://googlekoreablog.blogspot.com/2010/01/blog-post_6951.html"&gt;Korean version&lt;/a&gt;).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-1795283934234131705?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/1795283934234131705/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2010/01/what-right-people-are-heading-for-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/1795283934234131705'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/1795283934234131705'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2010/01/what-right-people-are-heading-for-in.html' title='What right people are heading for in this generation, &apos;Open&apos;'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-1665142882106945779</id><published>2009-12-28T23:56:00.003+09:00</published><updated>2010-07-02T16:44:43.801+09:00</updated><title type='text'>한국의 S/W 품질이 낮은 이유</title><content type='html'>나는 한국의 소프트웨어 품질이 낮다고 생각한다. 건축가가 자신이 설계한 건물에서는 못잔다는 말처럼 직업이 프로그래머이니까 그렇게 느낄 수도 있겠다고 생각할지 모르겠으나, 시간이 지나면 지날 수록 이러한 생각이 확고해 지기만 할 뿐이다.&lt;br /&gt;&lt;br /&gt;소프트웨어 품질이 낮다고 동의하는 대부분의 사람들이 개발자의 수준을 먼저 얘기하곤 한다. 심지어 개발자들도 스스로의 수준을 얘기하는 경우가 더러 있다. 하지만, 이건 아니다. 수압이 낮아서 물이 안나오는 데 애꿋은 수도꼭지 탓만 하는 것과 비슷하다.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;한국의 소프트웨어 품질이 낮은 이유는 프로그래머의 수준보다는 프로그래머의 의견이 무시되는 개발속도/기능 위주의 개발 환경 때문이다. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;프로그램 개발에 관련해 여러사람들과 얘기하다보면 항상하는 얘기가 있다. 어느정도 규모나 완성도를 요구하는 소프트웨어의 개발은 고층건물을 짓는 것과 비슷하다는 얘기다. 단층 주택은 별 고민 없이 뚝딱뚝딱 지을 수 있다. 하지만 100층짜리 건물은 얘기가 다르다. 지반 공사 부터 시작해서 하중 계산, 고층에서의 진동, 내장재의 물리적 특성, 전기 분배, 상하수 배관 시설, 낸난방 및 공조 등의 각 부분에서 물리, 전기, 인체공학 등등의 여러 기술이 복합적으로 사용되어 건물이 완성된다. 프로그램도 마찬가지다. 조엘 온 소프트웨어에는 웹페이지에서 간단한 파일을 업로드 하는 페이지를 예로들고 있다. 수 Kb의 파일을 업로드하는 코드는 10분이면 완성이다. 하지만 Gb라면 어떨까. 파일 업로드 상태를 모니터하는 쓰레드와 서버와 주기적으로 통신하여 상태를 확인하는 코드, 업로드 중에 발생하는 여러 상황에 대한 고려, 업로드 실패시 전송된 부분에 대한 후처리 등 생각할 일이 많다.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;하지만 이를 인식한 개발자의 의견이 반영되는 경우는 매우 드물다. 일반적으로는 그냥 업로드 파일의 크기를 수 Mb로 제한하고 대신 다른 다양한 기능을 더 추가하는 방향으로 진행된다. 기능적인 완성도를 추구하는 개발보다는 여러 가지 기능들을 빠른 시일에 화려한 UI와 개발하는 방향으로 진행된다. 굳이 일일이 예를들지 않아도 우리식(?)으로 개발된 프로그램들을 보면 대부분 이런 식이다.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A라는 거대 고객이 X라는 프로그램을 만들어 달란다. B사는 요구하는 기능을 충실히 구현하고 에러가 발생하지 않도록 많은 상황을 고려하여 신뢰성있는 소프트웨어를 개발하는데 집중한다. C사는 B사의 소프트웨어 보다 더 많은 기능을 넣고 화려한 UI로 장식한다. 고객 입장에서 최종 제품을 테스트 해보니 둘다 원하는 기능이 동작하는데 C사는 더 많은 기능을 제공하면서 더 이쁘다. 그래서 C사를 선택한다. 나중에 고객은 미처 예상하지 못했던 오류를 C사의 제품에서 발견한다. B사는 이러한 경우까지 고려했다고 처음에 설명했지만 고객은 오류를 직접 당하기 전까지는 이해하지 못한다. 결국 이런식의 제품 개발이 반복되어 B사도 다기능의 화려한 외양의 소프트웨어 개발에 매진하게 된다.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-1665142882106945779?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/1665142882106945779/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2009/12/sw.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/1665142882106945779'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/1665142882106945779'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2009/12/sw.html' title='한국의 S/W 품질이 낮은 이유'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-1070830250325481533</id><published>2009-12-25T23:06:00.001+09:00</published><updated>2009-12-25T23:06:57.658+09:00</updated><title type='text'>Brief on Signal</title><content type='html'>Review SIGNAL&lt;br /&gt;&lt;br /&gt;Signal can be used to control process. SIGKILL, SIGSTOP, SIGINT are well known types of signal. No process can mask SIGKILL and SIGSTOP.&lt;br /&gt;&lt;br /&gt;In a program, you can register signal handler function so that when a specific signal is sent to a process it can invoke registered signal handler function.&lt;br /&gt;&lt;br /&gt;And also you can block in a certain part of the code to wait signal.&lt;br /&gt;&lt;br /&gt;In multi-thread program, we can set signal mask so that only specified thread can handle the signal.&lt;br /&gt;&lt;br /&gt;* How to register signal handler.&lt;br /&gt;&lt;br /&gt;Though we've used the function signal() before, it's ANSI compatible one but not a standard. We can use sigaction() in the standard.&lt;br /&gt;&lt;br /&gt;sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);&lt;br /&gt;&lt;br /&gt;If handler is registered with the function above, handler will be called when the signal occurs.&lt;br /&gt;&lt;br /&gt;We use struct sigaction structure to register handler, to set mask, flags.&lt;br /&gt;&lt;br /&gt;&lt;font face="monospace"&gt; struct sigaction {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;void (*sa_handler)(int);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;void (*sa_sigaction)(int, siginfo_t *, void *); // kind of advanced&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// used with sigfillset(), sigemptyset(), sigaddset(), sigdelset()&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sigset_t sa_mask;&amp;nbsp;&amp;nbsp; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int sa_flags; // option flags like &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;/*&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SA_NOCLDSTOP, // child의 중지시 SIGCHLD 안받음&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SA_ONESHOT/SA_RESETHAND : 일회용 핸들러&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SA_NOMASK, SA_NODEFFER : 같은 시그널 발생을 block하지 않음&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SA_SIGINFO : 핸들러로 sa_sigaction을 사용&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*/&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;void (*sa_restorer)(void);&lt;br&gt; };&lt;br&gt; &lt;/font&gt;&lt;br /&gt;&lt;br /&gt;Sample code&lt;br /&gt;&lt;br /&gt;&lt;font face="monospace"&gt; &lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;stdio.h&amp;gt;&lt;/font&gt;&lt;br&gt; &lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/font&gt;&lt;br&gt; &lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;unistd.h&amp;gt;&lt;/font&gt;&lt;br&gt; &lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;signal.h&amp;gt;&lt;/font&gt;&lt;br&gt; &lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;string.h&amp;gt;&lt;/font&gt;&lt;br&gt; &lt;br&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;usr_handler(&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;signum);&lt;br&gt; &lt;br&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;main()&lt;br&gt; {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt;&amp;nbsp;sigaction sa_usr1;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt;&amp;nbsp;sigaction sa_usr2;&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;memset(&amp;amp;sa_usr1, &lt;font color="#ff00ff"&gt;0&lt;/font&gt;, &lt;font color="#a52a2a"&gt;&lt;b&gt;sizeof&lt;/b&gt;&lt;/font&gt;(&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt;&amp;nbsp;sigaction));&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sa_usr1.sa_handler = usr_handler;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sa_usr1.sa_flags = SA_NODEFER;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sigfillset(&amp;amp;sa_usr1.sa_mask);&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;memset(&amp;amp;sa_usr2, &lt;font color="#ff00ff"&gt;0&lt;/font&gt;, &lt;font color="#a52a2a"&gt;&lt;b&gt;sizeof&lt;/b&gt;&lt;/font&gt;(&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt;&amp;nbsp;sigaction));&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sa_usr2.sa_handler = usr_handler;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sa_usr2.sa_flags = SA_NODEFER;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sigemptyset(&amp;amp;sa_usr2.sa_mask);&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sigaction(&lt;font color="#ff00ff"&gt;SIGUSR1&lt;/font&gt;, &amp;amp;sa_usr1, &lt;font color="#ff00ff"&gt;NULL&lt;/font&gt;);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sigaction(&lt;font color="#ff00ff"&gt;SIGUSR2&lt;/font&gt;, &amp;amp;sa_usr2, &lt;font color="#ff00ff"&gt;NULL&lt;/font&gt;);&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;printf(&lt;font color="#ff00ff"&gt;&amp;quot;SIGUSR1, SIGUSR2 Registered!&lt;/font&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;);&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/font&gt;&amp;nbsp;(;;)&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pause();&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#ff00ff"&gt;EXIT_SUCCESS&lt;/font&gt;;&lt;br&gt; }&lt;br&gt; &lt;br&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;usr_handler(&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;signum)&lt;br&gt; {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;i;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/font&gt;&amp;nbsp;(i = &lt;font color="#ff00ff"&gt;0&lt;/font&gt;; i &amp;lt; &lt;font color="#ff00ff"&gt;5&lt;/font&gt;; i++)&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;printf(&lt;font color="#ff00ff"&gt;&amp;quot;[&lt;/font&gt;&lt;font color="#6a5acd"&gt;%d&lt;/font&gt;&lt;font color="#ff00ff"&gt;]Caught signal. will sleep 1 sec : SIGUSR&lt;/font&gt;&lt;font color="#6a5acd"&gt;%d&lt;/font&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;,i , (signum == &lt;font color="#ff00ff"&gt;SIGUSR1&lt;/font&gt;) ? &lt;font color="#ff00ff"&gt;1&lt;/font&gt;&amp;nbsp;: &lt;font color="#ff00ff"&gt;2&lt;/font&gt;);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sleep(&lt;font color="#ff00ff"&gt;1&lt;/font&gt;);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt; }&lt;br&gt; &lt;/font&gt;&lt;br /&gt;&lt;br /&gt;* How to block signal in a process&lt;br /&gt;&lt;br /&gt;sigprocmask() offers signal blocking. &lt;br /&gt;&lt;br /&gt;int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);&lt;br /&gt;&lt;br /&gt;If oldset is not NULL, current signal mask will be copied into oldset.&lt;br /&gt;&lt;br /&gt;* How to handle signal in multi-thread program.&lt;br /&gt;&lt;br /&gt;As a default, if program receive signal, all of its thread receive the signal and it will make,. a chaos and program will halt. Generally, people set signal mask so that signal can be handled by specific thread. &lt;br /&gt;&lt;br /&gt;Like sigprocmask, threre is pthread_sigmask(). If it's called in main(), all thread created after will have that signal mask. It it's called in a certain thread, only that thread will have that mask. In this way, we can specify which thread will receive signal.&lt;br /&gt;&lt;br /&gt;&lt;font face="monospace"&gt; &lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;stdio.h&amp;gt;&lt;/font&gt;&lt;br&gt; &lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/font&gt;&lt;br&gt; &lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;string.h&amp;gt;&lt;/font&gt;&lt;br&gt; &lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;signal.h&amp;gt;&lt;/font&gt;&lt;br&gt; &lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;pthread.h&amp;gt;&lt;/font&gt;&lt;br&gt; &lt;br&gt; &lt;font color="#a020f0"&gt;#define THREADNUM &lt;/font&gt;&lt;font color="#ff00ff"&gt;5&lt;/font&gt;&lt;br&gt; &lt;font color="#a020f0"&gt;#define LIFETIME &lt;/font&gt;&lt;font color="#ff00ff"&gt;10&lt;/font&gt;&lt;br&gt; &lt;br&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt;&amp;nbsp;s_thread_ctx&lt;br&gt; {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pthread_t tid;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;index;&lt;br&gt; }ctx[THREADNUM];&lt;br&gt; &lt;br&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;sig_handler(&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;);&lt;br&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;*worker(&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;*);&lt;br&gt; &lt;br&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;main()&lt;br&gt; {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;*res;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;i;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sigset_t sigmask, sigmask_old;&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sigfillset(&amp;amp;sigmask);&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;printf(&lt;font color="#ff00ff"&gt;&amp;quot;[MAIN] Masking all signals&lt;/font&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pthread_sigmask(SIG_SETMASK, &amp;amp;sigmask, &amp;amp;sigmask_old);&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/font&gt;&amp;nbsp;(i = &lt;font color="#ff00ff"&gt;0&lt;/font&gt;; i &amp;lt; THREADNUM; i++)&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ctx[i].index = i;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pthread_create(&amp;amp;ctx[i].tid, &lt;font color="#ff00ff"&gt;NULL&lt;/font&gt;, worker, (&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;*)&amp;amp;ctx[i]);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;printf(&lt;font color="#ff00ff"&gt;&amp;quot;[MAIN] Create &lt;/font&gt;&lt;font color="#6a5acd"&gt;%d&lt;/font&gt;&lt;font color="#ff00ff"&gt;th thread&lt;/font&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;, i);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;printf(&lt;font color="#ff00ff"&gt;&amp;quot;[MAIN] Joining threads&lt;/font&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/font&gt;&amp;nbsp;(i = &lt;font color="#ff00ff"&gt;0&lt;/font&gt;; i &amp;lt; THREADNUM; i++)&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pthread_join(ctx[i].tid, &amp;amp;res);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#ff00ff"&gt;0&lt;/font&gt;;&lt;br&gt; }&lt;br&gt; &lt;br&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;*worker(&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;*arg)&lt;br&gt; {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;i;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sigset_t sigmask;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt;&amp;nbsp;s_thread_ctx *ctx;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt;&amp;nbsp;sigaction sa;&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ctx = (&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt;&amp;nbsp;s_thread_ctx *)arg;&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sigfillset(&amp;amp;sigmask);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sigdelset(&amp;amp;sigmask, &lt;font color="#ff00ff"&gt;SIGINT&lt;/font&gt;);&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sa.sa_handler = sig_handler;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sigfillset(&amp;amp;sa.sa_mask);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sigaction(&lt;font color="#ff00ff"&gt;SIGINT&lt;/font&gt;, &amp;amp;sa, &lt;font color="#ff00ff"&gt;NULL&lt;/font&gt;);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt; &lt;font color="#a020f0"&gt;#ifdef HANDLER_THREAD&lt;/font&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;/*&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;nbsp;only last thread will catch SIGINT &lt;/font&gt;&lt;font color="#0000ff"&gt;*/&lt;/font&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt;&amp;nbsp;(ctx-&amp;gt;index == (THREADNUM - &lt;font color="#ff00ff"&gt;1&lt;/font&gt;))&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pthread_sigmask(SIG_SETMASK, &amp;amp;sigmask, &lt;font color="#ff00ff"&gt;NULL&lt;/font&gt;);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt; &lt;font color="#a020f0"&gt;#endif&lt;/font&gt;&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;/*&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;nbsp;Just waiting for LIFETIME seconds &lt;/font&gt;&lt;font color="#0000ff"&gt;*/&lt;/font&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/font&gt;&amp;nbsp;(i = &lt;font color="#ff00ff"&gt;0&lt;/font&gt;; i &amp;lt; LIFETIME; i++)&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sleep(&lt;font color="#ff00ff"&gt;1&lt;/font&gt;);&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;arg;&lt;br&gt; }&lt;br&gt; &lt;br&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;sig_handler(&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;signum)&lt;br&gt; {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt;&amp;nbsp;(signum == &lt;font color="#ff00ff"&gt;SIGINT&lt;/font&gt;)&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;printf(&lt;font color="#ff00ff"&gt;&amp;quot;[HANDLER] I've got SIGINT&lt;/font&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;;&lt;br&gt; }&lt;br&gt; &lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;* Handling signal and waiting signal.&lt;br /&gt;&lt;br /&gt;If handler is registered, it would be called when specified signal is sent. And we can also wait until the signal arrives. &lt;br /&gt;&lt;br /&gt;int sigsuspend(const sigset_t *mask);&lt;br /&gt;&lt;br /&gt;Function sigsuspend will block the program until specified signals in mask arrive.&lt;br /&gt;&lt;br /&gt;&lt;font face="monospace"&gt; &lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;signal.h&amp;gt;&lt;/font&gt;&lt;br&gt; &lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;stdio.h&amp;gt;&lt;/font&gt;&lt;br&gt; &lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;string.h&amp;gt;&lt;/font&gt;&lt;br&gt; &lt;br&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;handler(&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;signal)&lt;br&gt; {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;printf(&lt;font color="#ff00ff"&gt;&amp;quot;[Handler] Signal handled&lt;/font&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;;&lt;br&gt; }&lt;br&gt; &lt;br&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;main()&lt;br&gt; {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;sig;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sigset_t set;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt;&amp;nbsp;sigaction sa;&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;memset(&amp;amp;sa, &lt;font color="#ff00ff"&gt;0&lt;/font&gt;, &lt;font color="#a52a2a"&gt;&lt;b&gt;sizeof&lt;/b&gt;&lt;/font&gt;(&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt;&amp;nbsp;sigaction));&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sa.sa_handler = handler;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sigemptyset(&amp;amp;sa.sa_mask);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sigaddset(&amp;amp;sa.sa_mask, &lt;font color="#ff00ff"&gt;SIGUSR1&lt;/font&gt;);&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sigaction(&lt;font color="#ff00ff"&gt;SIGUSR1&lt;/font&gt;, &amp;amp;sa, &lt;font color="#ff00ff"&gt;NULL&lt;/font&gt;);&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sigfillset(&amp;amp;set);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sigdelset(&amp;amp;set, &lt;font color="#ff00ff"&gt;SIGUSR1&lt;/font&gt;);&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sig = sigsuspend(&amp;amp;set);&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;printf(&lt;font color="#ff00ff"&gt;&amp;quot;SIGUSR1 arrived&lt;/font&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;);&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#ff00ff"&gt;0&lt;/font&gt;;&lt;br&gt; }&lt;br&gt; &lt;br&gt; &lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;* Signal and process&lt;br /&gt;&lt;br /&gt;If a signal is sent to a certain process, it's also sent to all of its child as long as they have same process group id. That means, if a child become a process group leader, signal will not be propagated to it any more.&lt;br /&gt;&lt;br /&gt;cf. session  = process groups and processes, process group = processes, if pid == pgid, it's process group leader.&lt;br /&gt;&lt;br /&gt;related functions : setpid, setpgid, setpgrp, getsid, setsid&lt;br /&gt;&lt;br /&gt;&gt; kill -SIGUSR1 -1234 # to send SIGUSR1 signal to all processes which have pgid as 1234&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-1070830250325481533?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/1070830250325481533/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2009/12/brief-on-signal.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/1070830250325481533'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/1070830250325481533'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2009/12/brief-on-signal.html' title='Brief on Signal'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-7192465921955321562</id><published>2009-12-15T00:39:00.003+09:00</published><updated>2009-12-15T00:50:36.625+09:00</updated><title type='text'>When you want to make your function manage data in a thread-safe way.</title><content type='html'>When we want to make thread-specific memory area, we can use pthread_setspecific()/getspecfic() like below.&lt;br /&gt;&lt;br /&gt;&lt;font face="monospace"&gt; &lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/font&gt;&lt;br&gt; &lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;stdio.h&amp;gt;&lt;/font&gt;&lt;br&gt; &lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;pthread.h&amp;gt;&lt;/font&gt;&lt;br&gt; &lt;br&gt; &lt;font color="#a020f0"&gt;#define THREADNUM &lt;/font&gt;&lt;font color="#ff00ff"&gt;30&lt;/font&gt;&lt;br&gt; &lt;br&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt;&amp;nbsp;ctx_t {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pthread_t tid;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;index;&lt;br&gt; } ctx[THREADNUM];&lt;br&gt; &lt;br&gt; pthread_key_t t_key;&lt;br&gt; &lt;br&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt;&amp;nbsp;data_t {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;var_a;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;char&lt;/b&gt;&lt;/font&gt;&amp;nbsp;var_b;&lt;br&gt; };&lt;br&gt; &lt;br&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;*thread_func(&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;*);&lt;br&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;sub_func(pthread_key_t);&lt;br&gt; &lt;br&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;main()&lt;br&gt; {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;i;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;*res;&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pthread_key_create(&amp;amp;t_key, &lt;font color="#ff00ff"&gt;NULL&lt;/font&gt;);&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/font&gt;&amp;nbsp;(i = &lt;font color="#ff00ff"&gt;0&lt;/font&gt;; i &amp;lt; THREADNUM; i++)&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ctx[i].index = i;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pthread_create(&amp;amp;ctx[i].tid, &lt;font color="#ff00ff"&gt;NULL&lt;/font&gt;, thread_func, (&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;*)&amp;amp;ctx[i]);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;printf(&lt;font color="#ff00ff"&gt;&amp;quot;Joining!&lt;/font&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/font&gt;&amp;nbsp;(i = &lt;font color="#ff00ff"&gt;0&lt;/font&gt;; i &amp;lt; THREADNUM; i++)&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pthread_join(ctx[i].tid, &amp;amp;res);&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pthread_key_delete(t_key);&lt;br&gt; }&lt;br&gt; &lt;br&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;*thread_func(&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;*arg)&lt;br&gt; {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;i;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt;&amp;nbsp;data_t *pdata;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt;&amp;nbsp;ctx_t *ctx;&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ctx = (&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt;&amp;nbsp;ctx_t *)arg;&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pdata = (&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt;&amp;nbsp;data_t *)malloc(&lt;font color="#a52a2a"&gt;&lt;b&gt;sizeof&lt;/b&gt;&lt;/font&gt;(&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt;&amp;nbsp;data_t));&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pdata-&amp;gt;var_a = (ctx-&amp;gt;index + &lt;font color="#ff00ff"&gt;1&lt;/font&gt;) * &lt;font color="#ff00ff"&gt;10&lt;/font&gt;;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pdata-&amp;gt;var_b = &lt;font color="#ff00ff"&gt;0&lt;/font&gt;;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pthread_setspecific(t_key, pdata);&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/font&gt;&amp;nbsp;(i = &lt;font color="#ff00ff"&gt;0&lt;/font&gt;; i &amp;lt; &lt;font color="#ff00ff"&gt;10&lt;/font&gt;; i++)&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;printf(&lt;font color="#ff00ff"&gt;&amp;quot;Thread(&lt;/font&gt;&lt;font color="#6a5acd"&gt;%d&lt;/font&gt;&lt;font color="#ff00ff"&gt;) has value &lt;/font&gt;&lt;font color="#6a5acd"&gt;%d&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;nbsp;in its data space.&lt;/font&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;,&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ctx-&amp;gt;index, sub_func(t_key));&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#ff00ff"&gt;NULL&lt;/font&gt;;&lt;br&gt; }&lt;br&gt; &lt;br&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;sub_func(pthread_key_t key)&lt;br&gt; {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt;&amp;nbsp;data_t *pdata;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pdata = (&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt;&amp;nbsp;data_t *)pthread_getspecific(key);&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;pdata-&amp;gt;var_a;&lt;br&gt; }&lt;br&gt; &lt;/font&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-7192465921955321562?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/7192465921955321562/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2009/12/when-you-want-to-make-your-function.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/7192465921955321562'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/7192465921955321562'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2009/12/when-you-want-to-make-your-function.html' title='When you want to make your function manage data in a thread-safe way.'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-655232694245728083</id><published>2009-12-14T21:00:00.004+09:00</published><updated>2009-12-14T21:11:27.772+09:00</updated><title type='text'>Barrier mechanism</title><content type='html'>While we make threads and make it work, sometime we want to make them stop at a certain point of work flow. Barrier can be used to make them wait till the other threads end their jobs. Here is an example. 5th thread will sleep 5 seconds and the other threads will wait with pthread_barrier_wait().&lt;br /&gt;&lt;br /&gt;&lt;font face="monospace"&gt; &lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;pthread.h&amp;gt;&lt;/font&gt;&lt;br&gt; &lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;stdio.h&amp;gt;&lt;/font&gt;&lt;br&gt; &lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;errno.h&amp;gt;&lt;/font&gt;&lt;br&gt; &lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/font&gt;&lt;br&gt; &lt;br&gt; &lt;font color="#a020f0"&gt;#define THREADNUM &lt;/font&gt;&lt;font color="#ff00ff"&gt;5&lt;/font&gt;&lt;br&gt; &lt;br&gt; pthread_barrier_t barrier;&lt;br&gt; &lt;br&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt;&amp;nbsp;thread_ctx {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pthread_t tid;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;idx;&lt;br&gt; } thr_ctx[THREADNUM];&lt;br&gt; &lt;br&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;*start_thread(&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;*);&lt;br&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;clean_thread();&lt;br&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;exit_w_err(&lt;font color="#2e8b57"&gt;&lt;b&gt;const&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;char&lt;/b&gt;&lt;/font&gt;&amp;nbsp;*);&lt;br&gt; &lt;br&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;main()&lt;br&gt; {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;i;&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pthread_barrier_init(&amp;amp;barrier, &lt;font color="#ff00ff"&gt;NULL&lt;/font&gt;, THREADNUM);&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/font&gt;(i = &lt;font color="#ff00ff"&gt;0&lt;/font&gt;; i &amp;lt; THREADNUM; i++) {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;thr_ctx[i].idx = i;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt;&amp;nbsp;(pthread_create(&amp;amp;thr_ctx[i].tid, &lt;font color="#ff00ff"&gt;NULL&lt;/font&gt;, &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;start_thread, (&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;*)&amp;amp;thr_ctx[i])) {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;exit_w_err(&lt;font color="#ff00ff"&gt;&amp;quot;thread_create&amp;quot;&lt;/font&gt;);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;clean_thread();&lt;br&gt; }&lt;br&gt; &lt;br&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;*start_thread(&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;*in_ctx)&lt;br&gt; {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;res;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt;&amp;nbsp;thread_ctx *ctx;&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ctx = (&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt;&amp;nbsp;thread_ctx *)in_ctx;&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;/*&lt;/font&gt;&lt;br&gt; &lt;font color="#0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * thread will wait with barrier&lt;/font&gt;&lt;br&gt; &lt;font color="#0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color="#0000ff"&gt;*/&lt;/font&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt;&amp;nbsp;(ctx-&amp;gt;idx == THREADNUM - &lt;font color="#ff00ff"&gt;1&lt;/font&gt;) {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sleep(&lt;font color="#ff00ff"&gt;5&lt;/font&gt;);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;printf(&lt;font color="#ff00ff"&gt;&amp;quot;thread (&lt;/font&gt;&lt;font color="#6a5acd"&gt;%d&lt;/font&gt;&lt;font color="#ff00ff"&gt;) arrived&lt;/font&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;, ctx-&amp;gt;idx);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;else&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;printf(&lt;font color="#ff00ff"&gt;&amp;quot;thread (&lt;/font&gt;&lt;font color="#6a5acd"&gt;%d&lt;/font&gt;&lt;font color="#ff00ff"&gt;) started to wait&lt;/font&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;, ctx-&amp;gt;idx);&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt;&amp;nbsp;((res = pthread_barrier_wait(&amp;amp;barrier)) == &lt;font color="#ff00ff"&gt;EINVAL&lt;/font&gt;)&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;printf(&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;&lt;font color="#6a5acd"&gt;\t&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;nbsp;errno : &lt;/font&gt;&lt;font color="#6a5acd"&gt;%d&lt;/font&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;, res);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#ff00ff"&gt;NULL&lt;/font&gt;;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;in_ctx;&lt;br&gt; }&lt;br&gt; &lt;br&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;clean_thread(&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;)&lt;br&gt; {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;i;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;*res; &lt;font color="#0000ff"&gt;// dummy pointer.&lt;/font&gt;&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/font&gt;&amp;nbsp;(i = &lt;font color="#ff00ff"&gt;0&lt;/font&gt;; i &amp;lt; THREADNUM; i++) {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pthread_join(thr_ctx[i].tid, &amp;amp;res);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;;&lt;br&gt; }&lt;br&gt; &lt;br&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;exit_w_err(&lt;font color="#2e8b57"&gt;&lt;b&gt;const&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;char&lt;/b&gt;&lt;/font&gt;&amp;nbsp;*msg)&lt;br&gt; {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fprintf(&lt;font color="#ff00ff"&gt;stderr&lt;/font&gt;, &lt;font color="#ff00ff"&gt;&amp;quot;[ERROR] &lt;/font&gt;&lt;font color="#6a5acd"&gt;%s&lt;/font&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;, msg);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;exit(&lt;font color="#ff00ff"&gt;0&lt;/font&gt;);&lt;br&gt; }&lt;br&gt; &lt;/font&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-655232694245728083?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/655232694245728083/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2009/12/barrier-mechanism.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/655232694245728083'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/655232694245728083'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2009/12/barrier-mechanism.html' title='Barrier mechanism'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-88260800214325937</id><published>2009-12-10T18:39:00.000+09:00</published><updated>2009-12-10T18:41:02.835+09:00</updated><title type='text'>13 ways to make your web page faster.</title><content type='html'>1. Remove trivial text - comment, tab, space, etc.&lt;br /&gt;2. Cache ajax data if it's possible.&lt;br /&gt;3. Set your css, javascript out of the page and include them. So that it would be cached.&lt;br /&gt;4. Script, css optimization.&lt;br /&gt;5. Adjust ETags.&lt;br /&gt;6. Trim meta data of your img files. If you want resize it, send them as resized.&lt;br /&gt;7. Use gzip compression option so that compressed data will be transmitted.&lt;br /&gt;8. Javascript DOM Access is slow. Cache them if it's possible.&lt;br /&gt;9. Set your css on the top so that browser can render your page as it gets data.&lt;br /&gt;10. Browser can't download javascript in parallel way. Put them on the bottom.&lt;br /&gt;11. Don't use css expression, filter.&lt;br /&gt;12. Set cache in response header field.&lt;br /&gt;13. Note that some mobile devices cache only page smaller than 25kb.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-88260800214325937?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/88260800214325937/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2009/12/13-ways-to-make-your-web-page-faster.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/88260800214325937'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/88260800214325937'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2009/12/13-ways-to-make-your-web-page-faster.html' title='13 ways to make your web page faster.'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-5784124059869375561</id><published>2009-10-28T01:40:00.002+09:00</published><updated>2009-10-28T01:59:43.719+09:00</updated><title type='text'>Sample thread code using mutex</title><content type='html'>For your education.&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color:#000000" text="#f6f3e8"&gt;&lt;font face="monospace"&gt;&lt;br /&gt;&lt;font color="#96cbfe"&gt;#include &lt;/font&gt;&lt;font color="#a8ff60"&gt;&amp;lt;unistd.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#96cbfe"&gt;#include &lt;/font&gt;&lt;font color="#a8ff60"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#96cbfe"&gt;#include &lt;/font&gt;&lt;font color="#a8ff60"&gt;&amp;lt;string.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#96cbfe"&gt;#define THREAD_NUM &lt;/font&gt;&lt;font color="#ff73fd"&gt;5&lt;/font&gt;&lt;br /&gt;&lt;font color="#96cbfe"&gt;#define MUTEX_ENABLED &lt;/font&gt;&lt;font color="#ff73fd"&gt;0&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#ffffb6"&gt;struct&lt;/font&gt;&amp;nbsp;thread_ctx&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ffffb6"&gt;int&lt;/font&gt;&amp;nbsp;id;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pthread_t tid;&lt;br /&gt;} ctx_arr[THREAD_NUM];&lt;br /&gt;&lt;br /&gt;&lt;font color="#ffffb6"&gt;int&lt;/font&gt;&amp;nbsp;fd;&lt;br /&gt;pthread_mutex_t *mtx;&lt;br /&gt;pthread_mutexattr_t *mtxattr;&lt;br /&gt;&lt;br /&gt;&lt;font color="#ffffb6"&gt;void&lt;/font&gt;&amp;nbsp;* t_worker(&lt;font color="#ffffb6"&gt;void&lt;/font&gt;&amp;nbsp;*arg)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ffffb6"&gt;int&lt;/font&gt;&amp;nbsp;i;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ffffb6"&gt;char&lt;/font&gt;&amp;nbsp;buf[&lt;font color="#ff73fd"&gt;10&lt;/font&gt;];&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ffffb6"&gt;struct&lt;/font&gt;&amp;nbsp;thread_ctx *ctx = (&lt;font color="#ffffb6"&gt;struct&lt;/font&gt;&amp;nbsp;thread_ctx *)arg;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sprintf(buf, &lt;font color="#a8ff60"&gt;&amp;quot;&lt;/font&gt;&lt;font color="#e18964"&gt;%d&lt;/font&gt;&lt;font color="#e18964"&gt;\n&lt;/font&gt;&lt;font color="#a8ff60"&gt;&amp;quot;&lt;/font&gt;, ctx-&amp;gt;id);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#6699cc"&gt;if&lt;/font&gt;&amp;nbsp;(MUTEX_ENABLED)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pthread_mutex_lock(mtx);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#7c7c7c"&gt;// critical section&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#6699cc"&gt;for&lt;/font&gt;&amp;nbsp;(i = &lt;font color="#ff73fd"&gt;0&lt;/font&gt;; i &amp;lt; &lt;font color="#ff73fd"&gt;4&lt;/font&gt;; i++)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;write(fd, buf, strlen(buf));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;usleep(&lt;font color="#ff73fd"&gt;100&lt;/font&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#6699cc"&gt;if&lt;/font&gt;&amp;nbsp;(MUTEX_ENABLED)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pthread_mutex_unlock(mtx);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#6699cc"&gt;return&lt;/font&gt;&amp;nbsp;(&lt;font color="#ffffb6"&gt;void&lt;/font&gt;&amp;nbsp;*)ctx;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;font color="#ffffb6"&gt;int&lt;/font&gt;&amp;nbsp;main()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ffffb6"&gt;int&lt;/font&gt;&amp;nbsp;i;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ffffb6"&gt;void&lt;/font&gt;&amp;nbsp;*res;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#7c7c7c"&gt;// open file&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fd = open(&lt;font color="#a8ff60"&gt;&amp;quot;result.dat&amp;quot;&lt;/font&gt;, O_CREAT|O_RDWR);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#6699cc"&gt;if&lt;/font&gt;&amp;nbsp;(fd &amp;lt; &lt;font color="#ff73fd"&gt;0&lt;/font&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;printf(&lt;font color="#a8ff60"&gt;&amp;quot;[ERROR] file open failure - &lt;/font&gt;&lt;font color="#e18964"&gt;%s&lt;/font&gt;&lt;font color="#a8ff60"&gt;.&lt;/font&gt;&lt;font color="#e18964"&gt;\n&lt;/font&gt;&lt;font color="#a8ff60"&gt;&amp;quot;&lt;/font&gt;, strerror(fd));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#6699cc"&gt;return&lt;/font&gt;&amp;nbsp;-&lt;font color="#ff73fd"&gt;1&lt;/font&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#7c7c7c"&gt;// init mutex&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mtx = (pthread_mutex_t *)malloc(&lt;font color="#ffffff"&gt;sizeof&lt;/font&gt;(pthread_mutex_t));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mtxattr = (pthread_mutexattr_t *)malloc(&lt;font color="#ffffff"&gt;sizeof&lt;/font&gt;(pthread_mutexattr_t));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pthread_mutexattr_init(mtxattr);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pthread_mutexattr_settype(mtxattr, PTHREAD_MUTEX_TIMED_NP);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pthread_mutex_init(mtx, mtxattr);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#6699cc"&gt;for&lt;/font&gt;&amp;nbsp;(i = &lt;font color="#ff73fd"&gt;0&lt;/font&gt;; i &amp;lt; THREAD_NUM; i++)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ctx_arr[i].id = i;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#6699cc"&gt;if&lt;/font&gt;&amp;nbsp;(pthread_create(&amp;amp;ctx_arr[i].tid, &lt;font color="#99cc99"&gt;NULL&lt;/font&gt;, t_worker,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&lt;font color="#ffffb6"&gt;void&lt;/font&gt;&amp;nbsp;*)(ctx_arr + i)) != &lt;font color="#ff73fd"&gt;0&lt;/font&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;printf(&lt;font color="#a8ff60"&gt;&amp;quot;[ERROR] pthread_create failure&lt;/font&gt;&lt;font color="#e18964"&gt;\n&lt;/font&gt;&lt;font color="#a8ff60"&gt;&amp;quot;&lt;/font&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#7c7c7c"&gt;// To join all threads.&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#6699cc"&gt;for&lt;/font&gt;&amp;nbsp;(i = &lt;font color="#ff73fd"&gt;0&lt;/font&gt;; i &amp;lt; THREAD_NUM; i++)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pthread_join(ctx_arr[i].tid, &amp;amp;res);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;printf(&lt;font color="#a8ff60"&gt;&amp;quot;[MSG] All threads are joined.&lt;/font&gt;&lt;font color="#e18964"&gt;\n&lt;/font&gt;&lt;font color="#a8ff60"&gt;&amp;quot;&lt;/font&gt;);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;close(fd);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;free(mtx);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;free(mtxattr);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#6699cc"&gt;return&lt;/font&gt;&amp;nbsp;&lt;font color="#ff73fd"&gt;0&lt;/font&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;result :&lt;br /&gt;&lt;br /&gt;cat result.dat # mutex off&lt;br /&gt;2&lt;br /&gt;1&lt;br /&gt;0&lt;br /&gt;1&lt;br /&gt;0&lt;br /&gt;1&lt;br /&gt;3&lt;br /&gt;0&lt;br /&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;4&lt;br /&gt;4&lt;br /&gt;4&lt;br /&gt;4&lt;br /&gt;3&lt;br /&gt;4&lt;br /&gt;4&lt;br /&gt;4&lt;br /&gt;4&lt;br /&gt;cat result.dat # mutex on&lt;br /&gt;1&lt;br /&gt;1&lt;br /&gt;1&lt;br /&gt;1&lt;br /&gt;0&lt;br /&gt;0&lt;br /&gt;0&lt;br /&gt;0&lt;br /&gt;2&lt;br /&gt;2&lt;br /&gt;2&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;3&lt;br /&gt;3&lt;br /&gt;3&lt;br /&gt;4&lt;br /&gt;4&lt;br /&gt;4&lt;br /&gt;4&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-5784124059869375561?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/5784124059869375561/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2009/10/sample-thread-code-using-mutex.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/5784124059869375561'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/5784124059869375561'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2009/10/sample-thread-code-using-mutex.html' title='Sample thread code using mutex'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-7089546958575827144</id><published>2009-10-21T00:49:00.002+09:00</published><updated>2009-10-21T00:52:35.158+09:00</updated><title type='text'>installing posix man pages</title><content type='html'>For example, if you can't get man pages for pthread_create,&lt;br /&gt;&lt;br /&gt;(Some blogs recommend you to install glibc-doc, but it wouldn't work.)&lt;br /&gt;&lt;br /&gt;just do 'sudo apt-get install manpages-posix-dev'&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-7089546958575827144?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/7089546958575827144/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2009/10/installing-posix-man-pages.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/7089546958575827144'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/7089546958575827144'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2009/10/installing-posix-man-pages.html' title='installing posix man pages'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-8133244313051600611</id><published>2009-08-18T01:00:00.002+09:00</published><updated>2009-08-18T01:13:40.863+09:00</updated><title type='text'>Using autocomplete plugin of jQuery with django</title><content type='html'>1. Download jQuery auto complete plugin &lt;a href="http://bassistance.de/jquery-plugins/jquery-plugin-autocomplete/"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;2. Unzip it.&lt;br /&gt;&lt;br /&gt;3. Copy below files from the unzipped onto your javascript directory.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;jquery.autocomplete.css&lt;/li&gt;&lt;li&gt;jquery.autocomplete.js&lt;/li&gt;&lt;li&gt;jquery.bgiframes.min.js&lt;/li&gt;&lt;li&gt;jquery.dimensions.js (from jquery.com)&lt;/li&gt;&lt;/ul&gt;4. Include them.&lt;br /&gt;&lt;br /&gt;5. If you want to activate auto complete onto the html tag with id 'qwerty', add following code onto your js code area.&lt;br /&gt;&lt;br /&gt;$(document).ready(function(){&lt;br /&gt;&amp;nbsp;&amp;nbsp;$("#qwerty").autocomplete{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;'/ajax/autocomplete',&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{multiple: true, multipleSeparator: ', '}&lt;br /&gt;&amp;nbsp;&amp;nbsp;);&lt;br /&gt;});&lt;br /&gt;&lt;br /&gt;6. Setup urls.py so that it can handle '/ajax/autocomplete' with ajax_autocomplete module.&lt;br /&gt;&lt;br /&gt;7. in views.py, make ajax_autocomplete module like,&lt;br /&gt;&lt;br /&gt;def ajax_autocomplete(request):&lt;br /&gt;&amp;nbsp;&amp;nbsp;if request.GET.has_key('q'):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# Write your code here (search dictionary or db, etc..)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# And put it onto res (separated with '\n').&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return HttpResponse(res)&lt;br /&gt;&amp;nbsp;&amp;nbsp;return HttpResponse()&lt;br /&gt;&lt;br /&gt;8. Done. Have fun :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-8133244313051600611?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/8133244313051600611/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2009/08/using-autocomplete-plugin-of-jquery.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/8133244313051600611'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/8133244313051600611'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2009/08/using-autocomplete-plugin-of-jquery.html' title='Using autocomplete plugin of jQuery with django'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-3010539626894832562</id><published>2009-08-04T18:23:00.002+09:00</published><updated>2009-08-04T18:35:19.208+09:00</updated><title type='text'>MSN proxy with ssh using Pidgin</title><content type='html'>If your company blocked MSN port and you have accessable server out of your company, use it as a proxy with ssh -D option.&lt;br /&gt;&lt;br /&gt;Set tunnel with '&gt;ssh -D 1234 yourserveraddress.com'.&lt;br /&gt;(You can use any port number instead of 1234.)&lt;br /&gt;&lt;br /&gt;Set proxy option in your pidgin.&lt;br /&gt;Host : localhost&lt;br /&gt;Port : 1234&lt;br /&gt;&lt;br /&gt;That's all. Have fun.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-3010539626894832562?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/3010539626894832562/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2009/08/msn-proxy-with-ssh-using-pidgin.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/3010539626894832562'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/3010539626894832562'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2009/08/msn-proxy-with-ssh-using-pidgin.html' title='MSN proxy with ssh using Pidgin'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-5209270287808153936</id><published>2009-08-03T08:52:00.002+09:00</published><updated>2009-08-03T09:15:53.607+09:00</updated><title type='text'>Using django - Accounts</title><content type='html'>Django auth system is in django.contrib.auth.&lt;br /&gt;(Included in INSTALLED_APPS as a default)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Login page&lt;/span&gt;&lt;br /&gt;You can use default django login handler.&lt;br /&gt;&lt;br /&gt;&amp;lt;urls.py&amp;gt;&lt;br /&gt;urlpatterns = patterns('',&lt;br /&gt;&amp;nbsp;&amp;nbsp;...&lt;br /&gt;&amp;nbsp;&amp;nbsp;(r'^login/$', 'django.contrib.auth.views.login')&lt;br /&gt;&amp;lt;eof&amp;gt;&lt;br /&gt;&lt;br /&gt;You need to make a template for login page.&lt;br /&gt;&lt;br /&gt;&amp;lt;templates/registration/login.html&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;lt;form methos='post' action='.'&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;label for='id_username'&amp;gt;Username : &amp;lt;/label&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;{{ form.username }}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;br&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;label for='id_password'&amp;gt;Password : &amp;lt;/label&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;{{ form.password }}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;br&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;input type='hidden' name='next' value='/'/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;input type='submit' value='Login'/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;lt;/form&amp;gt;&lt;br /&gt;&amp;lt;eof&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;User objects methods&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;is_authenticated()&lt;/li&gt;&lt;br /&gt;&lt;li&gt;get_full_name()&lt;/li&gt;&lt;br /&gt;&lt;li&gt;email_user(subject, message, from_email=None)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;set_password(raw_password)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;check_password(raw_password)&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Logout&lt;/span&gt;&lt;br /&gt;&amp;lt;views.py&amp;gt;&lt;br /&gt;from django.http import HttpResponseRedirect&lt;br /&gt;from django.contrib.auth import logout&lt;br /&gt;&lt;br /&gt;def logout_page(request):&lt;br /&gt;&amp;nbsp;&amp;nbsp;logout(request)&lt;br /&gt;&amp;nbsp;&amp;nbsp;return HttpResponseRedirect('/')&lt;br /&gt;&amp;lt;eof&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;urls.py&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;...&lt;br /&gt;&amp;nbsp;&amp;nbsp;(r'^logout/$', logout_page),&lt;br /&gt;&amp;nbsp;&amp;nbsp;...&lt;br /&gt;&amp;lt;eof&amp;gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-5209270287808153936?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/5209270287808153936/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2009/08/using-django-accounts.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/5209270287808153936'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/5209270287808153936'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2009/08/using-django-accounts.html' title='Using django - Accounts'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-4115750550956558863</id><published>2009-07-10T00:29:00.006+09:00</published><updated>2009-08-03T08:50:07.889+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='django'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Using django - database</title><content type='html'>Django seldom uses SQL. It uses python class to access DB.&lt;br /&gt;&lt;br /&gt;Pros. You can apply one code to various types of DB.&lt;br /&gt;&lt;br /&gt;In django database,&lt;br /&gt;- Data type is equal to table.&lt;br /&gt;- Class member is like a table field.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Designing data model&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Create data type(table) in ur sampleapp/models.py&lt;br /&gt;&amp;lt;models.py&amp;gt;&lt;br /&gt;from django.db import models&lt;br /&gt;&lt;br /&gt;class SampleTable(models.Model):&lt;br /&gt;&amp;nbsp;&amp;nbsp;fieldA = models.IntegerField(unique=True)&lt;br /&gt;&amp;lt;eof&amp;gt;&lt;br /&gt;&lt;br /&gt;Like IntegerField, there are also pre-defined field.&lt;br /&gt;- TextField, DateTimefield, EmailField, URLField, FileField&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Creating data type&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Check if you activated your application in settings.py.&lt;br /&gt;&amp;lt;settings.py&amp;gt;&lt;br /&gt;INSTALLED_APPS = (&lt;br /&gt;&amp;nbsp;&amp;nbsp;...&lt;br /&gt;&amp;nbsp;&amp;nbsp;'sampleproject.sampleapp',&lt;br /&gt;)&lt;br /&gt;&amp;lt;eof&amp;gt;&lt;br /&gt;&lt;br /&gt;Do DB sync&lt;br /&gt;&amp;gt; ./manage.py syncdb&lt;br /&gt;&lt;br /&gt;You can see which SQL were generated with,&lt;br /&gt;&amp;gt; ./manage.py sql sampleapp&lt;br /&gt;&lt;br /&gt;Note that it generate 'id' field automatically when it makes table.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Using DB Shell&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Like we use database console to execute SQLs in terminal,&lt;br /&gt;django also has shell.&lt;br /&gt;&amp;gt; ./manage.py shell&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; from sampleapp.models import *&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; record = SampleTable(fieldA=123)&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; record.fieldA&lt;br /&gt;123&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; record.save()&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; records = SampleTable.objects.all()&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; firstRecord = SampleTable.objects.get(id=1)&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; record.delete()&lt;br /&gt;&lt;br /&gt;Like above, you can create a record, save it into DB, get all records or single one, access by id and delete it.&lt;br /&gt;&lt;br /&gt;Note that until you save(), it just remain only in memory.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;User data model&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;'User' data model is already built in.&lt;br /&gt;&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; from django.contrib.auth.models import User&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; User.objects.all()&lt;br /&gt;&lt;br /&gt;User has many attributes like username, email and password.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-4115750550956558863?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/4115750550956558863/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2009/07/django-database.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/4115750550956558863'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/4115750550956558863'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2009/07/django-database.html' title='Using django - database'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-6620265482021561049</id><published>2009-07-09T18:12:00.004+09:00</published><updated>2009-07-09T18:50:49.629+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='django'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Using django - beginning</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Installing&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;gt; sudo apt-get install python-django&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Start project&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;gt; django-admin startproject sampleproject&lt;br /&gt;&lt;br /&gt;Then, directory sampleproject is created.&lt;br /&gt;You can run test server using manage.py in the directory.&lt;br /&gt;You can set details using setting.py.&lt;br /&gt;You can set urls using urls.py&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Setting DB(ex. SQLite)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Edit setting.py.&lt;br /&gt;- Set DATABASE_NAME, DATABASE_ENGINE&lt;br /&gt;&lt;br /&gt;Then create DB.&lt;br /&gt;&amp;gt; ./manage.py syncdb&lt;br /&gt;- Chose if you will set superuser account.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Run server&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;gt; ./manage.py runserver&lt;br /&gt;&lt;br /&gt;Check it with url 'http://localhost:8000/'&lt;br /&gt;(8000 is default.)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Create application&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In one project, you can have several web-applications. Django calls it as applications.&lt;br /&gt;&lt;br /&gt;Create with commands,&lt;br /&gt;&amp;gt; ./manage.py startapp sampleapp&lt;br /&gt;&lt;br /&gt;Directory sampleapp is then generated.&lt;br /&gt;&lt;br /&gt;Application is recommended to be designed with MVC model.&lt;br /&gt;&lt;br /&gt;In sampleapp directory,&lt;br /&gt;You can define http request handler function in the file views.py&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Implementing handler&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Example,&lt;br /&gt;&amp;lt;views.py&amp;gt;&lt;br /&gt;from django.http import HttpResponse&lt;br /&gt;&lt;br /&gt;def main(request):&lt;br /&gt;&amp;nbsp;&amp;nbsp;output = "&amp;lt;html&amp;gt;Welcome!&amp;lt;/html&amp;gt;"&lt;br /&gt;&amp;nbsp;&amp;nbsp;return HttpResponse(output)&lt;br /&gt;&amp;lt;eof&amp;gt;&lt;br /&gt;&lt;br /&gt;'request' has many informations about current requests.&lt;br /&gt;&lt;br /&gt;&amp;lt;urls.py&amp;gt;&lt;br /&gt;from sampleapp.views import *&lt;br /&gt;...&lt;br /&gt;urlpatterns = patterns('',&lt;br /&gt;&amp;nbsp;&amp;nbsp;(r'^$', main)&lt;br /&gt;)&lt;br /&gt;&amp;lt;eof&amp;gt;&lt;br /&gt;&lt;br /&gt;In 'r'^$', r means regular expression, ^ is first of uri and $ stands for the last.&lt;br /&gt;So it means '/' actually. Function main has been set as a handler for '/' above.&lt;br /&gt;&lt;br /&gt;Now, check your first page with browser using 'http://localhost:8000/'. Good job!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Regular expressions&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;You can use expressions like below&lt;br /&gt; . ^ $ * + ? | [a-z] \w \d&lt;br /&gt;\w means alphabet or '_'&lt;br /&gt;\d means one letter digit.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-6620265482021561049?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/6620265482021561049/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2009/07/using-django-beginning.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/6620265482021561049'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/6620265482021561049'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2009/07/using-django-beginning.html' title='Using django - beginning'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-9046319748530512369</id><published>2009-07-08T21:31:00.002+09:00</published><updated>2009-07-08T21:34:31.715+09:00</updated><title type='text'>Disable firefox disk cache</title><content type='html'>Enter about:config in search bar.&lt;br /&gt;&lt;br /&gt;set browser.cache.disk.enable as "false"&lt;br /&gt;&lt;p&gt;set browser.cache.disk.capacity  as "0"&lt;/p&gt;&lt;p&gt;set browser.cache.memory.capacity (ex. 14336 (256M))&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-9046319748530512369?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/9046319748530512369/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2009/07/disable-firefox-disk-cache.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/9046319748530512369'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/9046319748530512369'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2009/07/disable-firefox-disk-cache.html' title='Disable firefox disk cache'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-8065240577439646215</id><published>2009-06-19T13:54:00.005+09:00</published><updated>2009-07-09T18:12:05.375+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='mod_python'/><title type='text'>Howto install python and mod_python on linux</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Installing Python&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If you want to install it onto custom directory, for example like /home/you/opt/Python&lt;br /&gt;&lt;br /&gt;Get python sources from python.org&lt;br /&gt;&lt;br /&gt;Untar it.&lt;br /&gt;&lt;br /&gt;./configure --prefix=/home/you/opt/Python --exec-prefix=/home/you/opt/Python --enable-shared&lt;br /&gt;&lt;br /&gt;make; make install;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Installing mod_python&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Get mod_python from here http://httpd.apache.org/modules/python-download.cgi&lt;br /&gt;&lt;br /&gt;Untar it.&lt;br /&gt;&lt;br /&gt;./configure --prefix=/home/you/opt/mod_python --exec-prefix=/home/you/opt/mod_python --with-apxs=/home/you/opt/httpd/bin/apxs --with-python=/home/you/opt/Python/bin/python&lt;br /&gt;&lt;br /&gt;# because normal 'make install' needs 'su' access,&lt;br /&gt;make; make install_dso; make install_py_lib&lt;br /&gt;&lt;br /&gt;add below configurations into httpd.conf&lt;br /&gt;&lt;br /&gt;&lt;blockquote style="font-family: lucida grande;"&gt;LoadModule      python_module       modules/mod_python.so&lt;br /&gt;&lt;br /&gt;&amp;lt;Directory [absolute path]&amp;gt;&lt;br /&gt;AddHandler      mod_python .py&lt;br /&gt;PythonHandler   test&lt;br /&gt;PythonDebug On&lt;br /&gt;&amp;lt;/Directory&amp;gt;&lt;/blockquote&gt;Restart httpd. It'll works.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-8065240577439646215?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/8065240577439646215/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2009/06/howto-install-python-and-modpython-on.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/8065240577439646215'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/8065240577439646215'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2009/06/howto-install-python-and-modpython-on.html' title='Howto install python and mod_python on linux'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-3773451235803889747</id><published>2009-06-18T16:52:00.001+09:00</published><updated>2009-06-18T16:54:16.724+09:00</updated><title type='text'>Terminal login message and broadcasting message</title><content type='html'>Login message : /etc/motd&lt;br /&gt;&lt;br /&gt;Broadcast message : use 'wall' command&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-3773451235803889747?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/3773451235803889747/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2009/06/terminal-login-message-and-broadcasting.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/3773451235803889747'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/3773451235803889747'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2009/06/terminal-login-message-and-broadcasting.html' title='Terminal login message and broadcasting message'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-8851906578774367677</id><published>2009-06-18T11:38:00.002+09:00</published><updated>2009-06-18T11:41:35.304+09:00</updated><title type='text'>MySQL Installing DB and setting password</title><content type='html'>Before starting server, you need to install database to use.&lt;br /&gt;&lt;br /&gt;./mysql_install_db --datadir=&amp;lt;path where db is installed&amp;gt; --user=&amp;lt;dbuser&amp;gt;&lt;br /&gt;&lt;br /&gt;Now, you can start server.&lt;br /&gt;&lt;br /&gt;./bin/mysqld_safe --user=&amp;lt;user&amp;gt; --port=&amp;lt;dbport&amp;gt; --socket=&amp;lt;sockfile path&amp;gt; --datadir=&amp;lt;path where db is installed&amp;gt; &amp;amp;&lt;br /&gt;&lt;br /&gt;As a default, root user can login without password on console. This should be changed.&lt;br /&gt;&lt;br /&gt;mysql&amp;gt; delete from mysql.user where user = '' ; # disable anonymous login&lt;br /&gt;mysql&amp;gt; set password for 'root'@'localhost' = password('&amp;lt;root password&amp;gt;'); # set root password&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-8851906578774367677?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/8851906578774367677/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2009/06/mysql-installing-db-and-setting.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/8851906578774367677'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/8851906578774367677'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2009/06/mysql-installing-db-and-setting.html' title='MySQL Installing DB and setting password'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-4857665911834114228</id><published>2009-06-11T18:48:00.002+09:00</published><updated>2009-07-10T01:10:22.621+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='management'/><title type='text'>The way to program smartly.</title><content type='html'>Don't stick to one methodology.&lt;br /&gt;&lt;br /&gt;Things should be done as simply as possible.&lt;br /&gt;&lt;br /&gt;They don't read documents. Make it simple as possible.&lt;br /&gt;&lt;br /&gt;Requirements always changes.&lt;br /&gt;&lt;br /&gt;We don't need to fix tools or process. What we should matter is people.&lt;br /&gt;&lt;br /&gt;Organize your team less than 10.&lt;br /&gt;&lt;br /&gt;Don't draw all detail architecture. Just draw the big picture.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-4857665911834114228?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/4857665911834114228/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2009/06/way-to-program-smartly.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/4857665911834114228'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/4857665911834114228'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2009/06/way-to-program-smartly.html' title='The way to program smartly.'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-2122763114635529402</id><published>2009-06-08T16:53:00.002+09:00</published><updated>2009-06-08T17:04:05.781+09:00</updated><title type='text'>Httpd configuration for including expire times in response http header</title><content type='html'>&lt;ul&gt;&lt;li&gt;First, you need to compile httpd using --enable-expires option. Then it's compiled with expire module built-in your httpd binary(You can check it like, &gt; httpd -l).&lt;/li&gt;&lt;li&gt;Second, configuration file should include following setting.&lt;br /&gt;ExpiresActive On&lt;br /&gt;ExpireByType image/gif A25920000&lt;br /&gt;ExpireByType image/png A25920000&lt;br /&gt;ExpireByType image/jpg A25920000&lt;br /&gt;ExpireByType image/jpeg A25920000&lt;br /&gt;This means image file has its expire time as 2592000 seconds later (one month from now)&lt;/li&gt;&lt;li&gt;Now, you can check whether expire information is included in the response header like below&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_HMeTW73pU4s/SizFxoE6thI/AAAAAAAAAG4/5ZozPbd2RV0/s1600-h/cacheExpire.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 210px;" src="http://3.bp.blogspot.com/_HMeTW73pU4s/SizFxoE6thI/AAAAAAAAAG4/5ZozPbd2RV0/s400/cacheExpire.JPG" alt="" id="BLOGGER_PHOTO_ID_5344864314144241170" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-2122763114635529402?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/2122763114635529402/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2009/06/httpd-configuration-for-including.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/2122763114635529402'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/2122763114635529402'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2009/06/httpd-configuration-for-including.html' title='Httpd configuration for including expire times in response http header'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_HMeTW73pU4s/SizFxoE6thI/AAAAAAAAAG4/5ZozPbd2RV0/s72-c/cacheExpire.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-969098310228748534</id><published>2009-06-08T16:51:00.003+09:00</published><updated>2009-06-08T16:53:17.078+09:00</updated><title type='text'>Httpd(apache) server status using scoreboard</title><content type='html'>If you're using httpd as a web server, you can check the status of your server using following url.&lt;br /&gt;&lt;br /&gt;"http://localhost:&lt;port&gt;/server-status?auto"&lt;br /&gt;&lt;br /&gt;You can check how many workers are busy or idle by checking response page&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-969098310228748534?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/969098310228748534/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2009/06/httpdapache-server-status-using.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/969098310228748534'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/969098310228748534'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2009/06/httpdapache-server-status-using.html' title='Httpd(apache) server status using scoreboard'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-5874680714712873443</id><published>2009-06-04T14:15:00.001+09:00</published><updated>2009-06-04T14:17:24.394+09:00</updated><title type='text'>Asshole Driven Development</title><content type='html'>&lt;a href="http://www.scottberkun.com/blog/2007/asshole-driven-development/"&gt;Asshole Driven Development&lt;/a&gt; :  Any team where the biggest jerk makes all the big decisions is asshole driven development.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-5874680714712873443?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/5874680714712873443/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2009/06/asshole-driven-development.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/5874680714712873443'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/5874680714712873443'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2009/06/asshole-driven-development.html' title='Asshole Driven Development'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-9202116889933957674</id><published>2009-05-29T23:32:00.004+09:00</published><updated>2009-06-09T23:40:44.879+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fonts'/><category scheme='http://www.blogger.com/atom/ns#' term='environment'/><title type='text'>Good fonts for programming</title><content type='html'>for linux users,&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Bitmap Vera Sans Mono Roman (size 9)&lt;/li&gt;&lt;/ul&gt;for windows users,&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Andale Mono&lt;/li&gt;&lt;/ul&gt;Good vim colorscheme&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://blog.infinitered.com/entries/show/8"&gt;ir_black.vim&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;Ps. You need to adjust anti-aliasing or clear-type setting for using them.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-9202116889933957674?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/9202116889933957674/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2009/05/good-fonts-for-programming.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/9202116889933957674'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/9202116889933957674'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2009/05/good-fonts-for-programming.html' title='Good fonts for programming'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-8356249286653529041</id><published>2009-05-20T13:57:00.001+09:00</published><updated>2009-05-20T13:59:21.897+09:00</updated><title type='text'>jquery</title><content type='html'>Jquery is simple javascript library like dojo or prototype.&lt;br /&gt;&lt;br /&gt;Jquery follows MIT, GPL license and we can use it through &lt;a href="http://jquery.com/"&gt;here&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-8356249286653529041?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/8356249286653529041/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2009/05/jquery.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/8356249286653529041'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/8356249286653529041'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2009/05/jquery.html' title='jquery'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-7018235161727992932</id><published>2009-05-19T11:18:00.001+09:00</published><updated>2009-05-19T11:23:17.863+09:00</updated><title type='text'>Google's tcmalloc and google-perftools</title><content type='html'>&lt;a href="http://google-perftools.googlecode.com/svn/trunk/doc/tcmalloc.html"&gt;tcmalloc&lt;/a&gt; - Thread Cache Malloc&lt;br /&gt;&lt;br /&gt;&lt;a href="http://code.google.com/p/google-perftools/"&gt;perftools&lt;/a&gt; - Performance Tools&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="display: block;" id="formatbar_Buttons"&gt;&lt;span class="on down" style="display: block;" id="formatbar_CreateLink" title="링크" onmouseover="ButtonHoverOn(this);" onmouseout="ButtonHoverOff(this);" onmouseup="" onmousedown="CheckFormatting(event);FormatbarButton('richeditorframe', this, 8);ButtonMouseDown(this);"&gt;&lt;img src="http://www.blogger.com/img/blank.gif" alt="링크" class="gl_link" border="0" /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-7018235161727992932?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/7018235161727992932/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2009/05/googles-tcmalloc-and-google-perftools.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/7018235161727992932'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/7018235161727992932'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2009/05/googles-tcmalloc-and-google-perftools.html' title='Google&apos;s tcmalloc and google-perftools'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-2914155581455015533</id><published>2009-04-22T14:48:00.005+09:00</published><updated>2009-04-22T17:37:16.017+09:00</updated><title type='text'>Connecting Oracle Database with oracle instant client using PHP in Linux</title><content type='html'>We can connect Oracle db without oracle client if only we can use instant client instead. But this is for 10g or later version of db.&lt;br /&gt;&lt;br /&gt;1. You need to have an account for www.oracle.com. Create a new through &lt;a href="https://profile.oracle.com/jsp/reg/createUser.jsp?act=5&amp;amp;src=1180588&amp;amp;tid=262&amp;amp;owner=3&amp;amp;nexturl=&amp;amp;language=us"&gt;&lt;span class="profile"&gt;Register for a free Oracle Web account)&lt;/span&gt;&lt;/a&gt; .&lt;br /&gt;&lt;br /&gt;2. Choose which release of Oracle instant client you need &lt;a href="http://www.oracle.com/technology/software/tech/oci/instantclient/index.html?rssid=rss_otn_soft"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;3. Accept license agreement, find the version you need, click to download. (I chose version 10.2 of basic, sdk and sqlplus package. Note that some version may not work in your system.)&lt;span class="boldbodycopy"&gt;&lt;br /&gt;&lt;br /&gt;4. Install it. You can install it using rpm or manually using .zip files.&lt;br /&gt;&lt;br /&gt;5. If you downloaded sqlplus package and running on linux, you can check whether it works properly with command '&gt;export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:[instant client's path]; ./sqlplus --help' in instantclient directory.&lt;br /&gt;&lt;br /&gt;6. Now's the time to test db connection using sqlplus. Make text file with the name 'tnsnames.ora' with connect information like below.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;YOURNAME =&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt; (DESCRIPTION =&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   (ADDRESS_LIST =&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;     (ADDRESS = (PROTOCOL = TCP)(HOST = XXX.XXX.XXX.XXX)(PORT = XXXX))&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   )&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   (CONNECT_DATA =&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;     (SID = XXXXX)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   )&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt; )&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;7. Set environment variables like below.&lt;br /&gt;&lt;br /&gt;&gt; export ORACLE_HOME=&lt;path&gt;&lt;br /&gt;&gt; export TNS_ADMIN=&lt;path&gt;&lt;br /&gt;&lt;br /&gt;8. &gt; now try to connect with id/pw. Does it work? Fine!&lt;br /&gt;&lt;br /&gt;9. To make it work, you should recompile php module with the option like below.&lt;br /&gt;&lt;br /&gt;--with-oci8=instantclient,&lt;instant&gt;&lt;br /&gt;&lt;br /&gt;10. Check whether follow env variables set set properly&lt;br /&gt;&lt;br /&gt;export TNS_ADMIN=/yoursystem/yourpath   # where tnsnames.ora exists&lt;br /&gt;export NLS_LANG=KOREAN_KOREA.UTF8  # set encoding for your locale&lt;br /&gt;&lt;br /&gt;11. Check with . If you can find oci8 section in the information, it's done.&lt;br /&gt;&lt;br /&gt;12. Now you can connect to oracle db using php functions. Let's see sample code.&lt;br /&gt;&lt;br /&gt;&lt;div style='font-size:12px' text="#000000"&gt;&lt;font face="monospace"&gt;&lt;br /&gt;&lt;font color="#6a5acd"&gt;&amp;lt;?&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;// ORA_SERVER : defined in tnsnames.ora&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;// Connect&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;$&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;conn&lt;/font&gt;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;=&lt;/b&gt;&lt;/font&gt;&amp;nbsp;oci_connect&lt;font color="#6a5acd"&gt;(&lt;/font&gt;'&lt;font color="#ff00ff"&gt;user&lt;/font&gt;', '&lt;font color="#ff00ff"&gt;pass&lt;/font&gt;', '&lt;font color="#ff00ff"&gt;ORA_SERVER&lt;/font&gt;'&lt;font color="#6a5acd"&gt;)&lt;/font&gt;;&lt;br&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#6a5acd"&gt;(&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;!&lt;/b&gt;&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;$&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;conn&lt;/font&gt;&lt;font color="#6a5acd"&gt;)&lt;/font&gt;&amp;nbsp;&lt;font color="#6a5acd"&gt;{&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;$&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;e&lt;/font&gt;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;=&lt;/b&gt;&lt;/font&gt;&amp;nbsp;oci_error&lt;font color="#6a5acd"&gt;()&lt;/font&gt;;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a020f0"&gt;print&lt;/font&gt;&amp;nbsp;&lt;font color="#008b8b"&gt;htmlentities&lt;/font&gt;&lt;font color="#6a5acd"&gt;(&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;$&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;e&lt;/font&gt;&lt;font color="#6a5acd"&gt;[&lt;/font&gt;'&lt;font color="#ff00ff"&gt;message&lt;/font&gt;'&lt;font color="#6a5acd"&gt;])&lt;/font&gt;;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;exit&lt;/b&gt;&lt;/font&gt;;&lt;br&gt;&lt;br /&gt;&lt;font color="#6a5acd"&gt;}&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;// Execute query&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;$&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;query&lt;/font&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;=&lt;/b&gt;&lt;/font&gt;&amp;nbsp;'&lt;font color="#ff00ff"&gt;SELECT * FROM SAMPLETABLE&lt;/font&gt;';&lt;br&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;$&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;stid&lt;/font&gt;&amp;nbsp;&amp;nbsp; &lt;font color="#a52a2a"&gt;&lt;b&gt;=&lt;/b&gt;&lt;/font&gt;&amp;nbsp;oci_parse&lt;font color="#6a5acd"&gt;(&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;$&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;conn&lt;/font&gt;, &lt;font color="#a52a2a"&gt;&lt;b&gt;$&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;query&lt;/font&gt;&lt;font color="#6a5acd"&gt;)&lt;/font&gt;;&lt;br&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#6a5acd"&gt;(&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;!&lt;/b&gt;&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;$&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;stid&lt;/font&gt;&lt;font color="#6a5acd"&gt;)&lt;/font&gt;&amp;nbsp;&lt;font color="#6a5acd"&gt;{&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;$&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;e&lt;/font&gt;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;=&lt;/b&gt;&lt;/font&gt;&amp;nbsp;oci_error&lt;font color="#6a5acd"&gt;(&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;$&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;conn&lt;/font&gt;&lt;font color="#6a5acd"&gt;)&lt;/font&gt;;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a020f0"&gt;print&lt;/font&gt;&amp;nbsp;&lt;font color="#008b8b"&gt;htmlentities&lt;/font&gt;&lt;font color="#6a5acd"&gt;(&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;$&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;e&lt;/font&gt;&lt;font color="#6a5acd"&gt;[&lt;/font&gt;'&lt;font color="#ff00ff"&gt;message&lt;/font&gt;'&lt;font color="#6a5acd"&gt;])&lt;/font&gt;;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;exit&lt;/b&gt;&lt;/font&gt;;&lt;br&gt;&lt;br /&gt;&lt;font color="#6a5acd"&gt;}&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;$&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;r&lt;/font&gt;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;=&lt;/b&gt;&lt;/font&gt;&amp;nbsp;oci_execute&lt;font color="#6a5acd"&gt;(&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;$&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;stid&lt;/font&gt;, OCI_DEFAULT&lt;font color="#6a5acd"&gt;)&lt;/font&gt;;&lt;br&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#6a5acd"&gt;(&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;!&lt;/b&gt;&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;$&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;r&lt;/font&gt;&lt;font color="#6a5acd"&gt;)&lt;/font&gt;&amp;nbsp;&lt;font color="#6a5acd"&gt;{&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;$&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;e&lt;/font&gt;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;=&lt;/b&gt;&lt;/font&gt;&amp;nbsp;oci_error&lt;font color="#6a5acd"&gt;(&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;$&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;stid&lt;/font&gt;&lt;font color="#6a5acd"&gt;)&lt;/font&gt;;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a020f0"&gt;echo&lt;/font&gt;&amp;nbsp;&lt;font color="#008b8b"&gt;htmlentities&lt;/font&gt;&lt;font color="#6a5acd"&gt;(&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;$&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;e&lt;/font&gt;&lt;font color="#6a5acd"&gt;[&lt;/font&gt;'&lt;font color="#ff00ff"&gt;message&lt;/font&gt;'&lt;font color="#6a5acd"&gt;])&lt;/font&gt;;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;exit&lt;/b&gt;&lt;/font&gt;;&lt;br&gt;&lt;br /&gt;&lt;font color="#6a5acd"&gt;}&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;// Fetch results&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;while&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#6a5acd"&gt;(&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;$&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;row&lt;/font&gt;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;=&lt;/b&gt;&lt;/font&gt;&amp;nbsp;oci_fetch_array&lt;font color="#6a5acd"&gt;(&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;$&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;stid&lt;/font&gt;, OCI_RETURN_NULLS&lt;font color="#6a5acd"&gt;))&lt;/font&gt;&amp;nbsp;&lt;font color="#6a5acd"&gt;{&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;foreach&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#6a5acd"&gt;(&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;$&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;row&lt;/font&gt;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;as&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;$&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;item&lt;/font&gt;&lt;font color="#6a5acd"&gt;)&lt;/font&gt;&amp;nbsp;&lt;font color="#6a5acd"&gt;{&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a020f0"&gt;print&lt;/font&gt;&amp;nbsp;&lt;font color="#6a5acd"&gt;(&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;$&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;item&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;?&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;htmlentities&lt;/font&gt;&lt;font color="#6a5acd"&gt;(&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;$&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;item&lt;/font&gt;&lt;font color="#6a5acd"&gt;)&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;:&lt;/b&gt;&lt;/font&gt;'&lt;font color="#ff00ff"&gt;&amp;amp;nbsp;&lt;/font&gt;'&lt;font color="#6a5acd"&gt;)&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;.&lt;/b&gt;&lt;/font&gt;'&lt;font color="#ff00ff"&gt;&amp;lt;br&amp;gt;&lt;/font&gt;';&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#6a5acd"&gt;}&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;font color="#6a5acd"&gt;}&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;// Close&lt;/font&gt;&lt;br&gt;&lt;br /&gt;oci_close&lt;font color="#6a5acd"&gt;(&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;$&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;conn&lt;/font&gt;&lt;font color="#6a5acd"&gt;)&lt;/font&gt;;&lt;br&gt;&lt;br /&gt;&lt;font color="#6a5acd"&gt;?&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-2914155581455015533?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/2914155581455015533/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2009/04/connecting-oracle-database-with-oracle.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/2914155581455015533'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/2914155581455015533'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2009/04/connecting-oracle-database-with-oracle.html' title='Connecting Oracle Database with oracle instant client using PHP in Linux'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-5668512986470815395</id><published>2009-03-02T15:36:00.002+09:00</published><updated>2009-03-02T15:37:12.464+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tool'/><category scheme='http://www.blogger.com/atom/ns#' term='xml'/><title type='text'>XML Document Validation Tool</title><content type='html'>If that's just for debug and development purpose, simply use xmllint.&lt;br /&gt;&lt;br /&gt;&gt; xmllint yourDocument.xml&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-5668512986470815395?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/5668512986470815395/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2009/03/xml-document-validation-tool.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/5668512986470815395'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/5668512986470815395'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2009/03/xml-document-validation-tool.html' title='XML Document Validation Tool'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-5140671520748256724</id><published>2009-02-17T15:41:00.001+09:00</published><updated>2009-02-17T15:43:41.267+09:00</updated><title type='text'>제목 보고 당했다.</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_HMeTW73pU4s/SZpcjUaLCsI/AAAAAAAAAEk/P9mUkhDzKfI/s1600-h/c99.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 144px; height: 200px;" src="http://1.bp.blogspot.com/_HMeTW73pU4s/SZpcjUaLCsI/AAAAAAAAAEk/P9mUkhDzKfI/s200/c99.jpg" alt="" id="BLOGGER_PHOTO_ID_5303653273025841858" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span id="TitleBar"&gt;&lt;span class="txt13p" style="letter-spacing: -1px;"&gt;"&lt;a href="http://cosmos.ssu.ac.kr/c99/contents.html"&gt;새표준 C C99&lt;/a&gt;"  C99 표준 번역서 인줄 알고 냉큼 샀는데, C 기초 프로그래밍 책이다.&lt;br /&gt;&lt;br /&gt;이런,.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-5140671520748256724?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/5140671520748256724/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2009/02/blog-post.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/5140671520748256724'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/5140671520748256724'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2009/02/blog-post.html' title='제목 보고 당했다.'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_HMeTW73pU4s/SZpcjUaLCsI/AAAAAAAAAEk/P9mUkhDzKfI/s72-c/c99.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-5586469821383503776</id><published>2009-02-12T22:32:00.000+09:00</published><updated>2009-02-12T22:33:34.219+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Unicode'/><title type='text'>All about unicode</title><content type='html'>&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 굴림; font-size: 13px; line-height: 19px;"&gt;(korean) &lt;a href="http://www.kristalinfo.com/K-Lab/unicode/Unicode_intro-kr.html" target="_blank" onclick="return goOtherCR(this, 'a=web*w.tit&amp;amp;r=1&amp;amp;i=328dddfc8a548eb26jiWjtu1g471mKjStwQqRg%3D%3D&amp;amp;u='+urlencode(this.href ? this.href : location.href))" class="link" style="text-decoration: underline; color: rgb(153, 32, 155); "&gt;진숙의 &lt;strong&gt;유니코드&lt;/strong&gt; 입&lt;strong&gt;문서&lt;/strong&gt;&lt;/a&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-5586469821383503776?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/5586469821383503776/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2009/02/all-about-unicode.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/5586469821383503776'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/5586469821383503776'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2009/02/all-about-unicode.html' title='All about unicode'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-7388294282682546918</id><published>2008-10-26T17:18:00.002+09:00</published><updated>2008-10-26T17:31:40.989+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='algorithm'/><title type='text'>Backtracking</title><content type='html'>백트래킹은 주어진 어떤 집합에 대해 조건을 만족하는 모든 부분집합(subset)을 구하는 정형화된 알고리즘이다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;/*&lt;br /&gt;  a[] : 답중 하나가 되는 부분 집합을 저장할 공간&lt;br /&gt;  n : 전체 집합의 크기&lt;br /&gt;  k : 현재 집합의 크기&lt;br /&gt;  candidates[] : 조건들 (예, 포함되거나 안되거나)&lt;br /&gt;*/&lt;br /&gt;void process_solution(int a, int k)&lt;br /&gt;{&lt;br /&gt;  for (int i = 1; i &lt;= k;)&lt;br /&gt;    if (a[i] == 1) printf ("...", i);&lt;br /&gt;}&lt;br /&gt;void construct_candidates( ... c, *nc)&lt;br /&gt;{&lt;br /&gt;  c[...] = condition&lt;br /&gt;  ...&lt;br /&gt;  *nc = X; // number of conditions&lt;br /&gt;  return;&lt;br /&gt;}&lt;br /&gt;backtrack(a[], k, n)&lt;br /&gt;{&lt;br /&gt;  if (k == n)&lt;br /&gt;    process_solution(a, k);&lt;br /&gt;  else&lt;br /&gt;    k++;&lt;br /&gt;    construct_candidates(c, &amp;nc);&lt;br /&gt;    for (int i = 0; i &lt; nc; i++)&lt;br /&gt;      a[k] = c[i]; // set condition&lt;br /&gt;      backtrack(a, k, n);&lt;br /&gt;}&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;  a = arr[MAXSIZE];&lt;br /&gt;  backtrack(a, 0, n);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-7388294282682546918?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/7388294282682546918/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/10/backtracking.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/7388294282682546918'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/7388294282682546918'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/10/backtracking.html' title='Backtracking'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-585553772965519833</id><published>2008-10-26T09:17:00.004+09:00</published><updated>2008-10-26T09:28:20.492+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='algorithm'/><title type='text'>Minimizing Memory Cost</title><content type='html'>프로그램이 사용하는 메모리를 절약하기 위한 방법들에 대해 정리해 보자.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;일단 단순해져야 한다.&lt;br /&gt;메모리의 구조를 단순하게 하면 크기도 줄어들고 실행속도도 빨리질 수 있다. (세금 계산 테이블을 메모리에 넣는 대신 이를 표현하는 하나의 함수를 사용할 수 있다)&lt;/li&gt;&lt;li&gt;메모리 절약을 위해 사용되는 기법들은 아래와 같다.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Sparse data structure&lt;/span&gt;&lt;br /&gt;는 대부분의 엔트리가 같은 값을 가지는 데이터 구조를 의미하는데, 이를 리스트와 같은 자료구조를 사용하면 메모리를 절약할 수 있다. 혹은 같은 값을 가지는 부분만 떼어 내어 별도로 저장하므로 같은 값을 중복으로 저장하는 overhead를 줄일 수 있다.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;데이터 압축&lt;/span&gt;&lt;br /&gt;은 말그대로 압축을 하거나, 한 자료 타입안에 여러 데이터를 동시에 넣는 방법이다. (두 지점사이의 거리를 나타내는 행렬, 좌표 등)&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;할당 정책의 변경&lt;/span&gt;&lt;br /&gt;을 통해 메모리를 절약할 수 있다. 공간을 정적으로 미리할당하지 않고 필요할 때 동적으로 할당해주는 것을 예로 들 수 있다.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;물론 메모리 절약에서도 Amdahl's law 가 적용된다.  특정 데이터 구조가 전체 메모리 공간의 대부분을 차지하는 경우를 찾아 개선하면 효율적으로 메모리를 절약할 수 있다.&lt;/li&gt;&lt;li&gt;때로는 메모리 절약을 위해 성능을 희생해야하는 Trade-off 가 발생한다.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-585553772965519833?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/585553772965519833/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/10/minimizing-memory-cost.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/585553772965519833'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/585553772965519833'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/10/minimizing-memory-cost.html' title='Minimizing Memory Cost'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-2284873637960439878</id><published>2008-10-22T14:25:00.004+09:00</published><updated>2008-10-22T18:50:01.775+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='algorithm'/><title type='text'>Using Macro is not always faster.</title><content type='html'>함수 콜하는 부분을 매크로로 치환하면 일반적으로 성능이 빨라진다. 그러나 항상 그렇지는 않다.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#define MAX(a,b) ((a) &gt; (b) ? (a) : (b))&lt;br /&gt;&lt;br /&gt;float arrmax(int n)&lt;br /&gt;{&lt;br /&gt; if (n == 1)&lt;br /&gt;     return x[0];&lt;br /&gt; else&lt;br /&gt; {&lt;br /&gt;         return MAX(x[n-1], arrmax(n-1));&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;위 코드는 매우 느리다. 배열의 최대값을 리턴하는 코드인데, 배열의 크기가 30개만 넘어가도 실행 속도가 수초이상 걸리게 된다. 왜냐하면 매크로 부분이 x[n-1] &gt; arrmax(n-1) ? x[n-1] : arrmax(n-1) 로 치환되면서 수행시간이 (함수가 호출되는 횟수가) 매크로 대신 함수로 구현할 때 보다 O(n) 에서 O(2^n) 이 되기 때문이다. 재귀적 호출에서 이런 실수는 상당한 성능저하를 낳게 되니 주의 하자.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-2284873637960439878?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/2284873637960439878/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/10/using-macro-is-not-always-faster.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/2284873637960439878'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/2284873637960439878'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/10/using-macro-is-not-always-faster.html' title='Using Macro is not always faster.'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-386170039923299981</id><published>2008-10-14T21:37:00.003+09:00</published><updated>2008-10-14T21:55:22.134+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming Pearls'/><title type='text'>Code Tuning</title><content type='html'>코드 튜닝은 기본적으로 구조에 적합한 효율성을 얻는데서 만족해야지 지나친 최적화나 그 반대의 경우로 치우치면 곤란하다.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Hotspot (병목) 찾아내기&lt;/li&gt;&lt;li&gt;그 부분 최적화 하기&lt;/li&gt;&lt;/ol&gt;의 식으로 진행하는데, 코드 튜닝의 팁&amp;amp;예를 들면 아래와 같다.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;나눗셈은 다른 연산보다 비용이 많이 든다.&lt;/span&gt; 그래서 가능한 경우 아래처럼 할 수 있다고 한다.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;k = (a+b) % n; // 요거 대신&lt;br /&gt;k = a + b; if (k&gt;=n) k -=n; // 요렇게&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;경우에 따라 2배의 성능 차이가 있다고 한다.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;메모리 접근 빈도나 계산 시간 중 오래 걸리는 것을 개선해라&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;매크로가 항상 성능을 개선시키는 것은 아니다.&lt;/span&gt; recursive하게 호출되는 경우 책에서는 경우에 따라 1,000배까지 느려진다고 한다. 이건,.. 테스트 해봐야 겠다. (물론 매크로를 써서 성능이 향상된 경우도 있다.)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;for loop 의 비교횟수를 줄여 5% 성능향상을 가져올 수도 있다.&lt;/span&gt; 좀, 심하긴 한데,&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;int search(int t) {&lt;br /&gt; hold = x[n];&lt;br /&gt; x[n] = t;&lt;br /&gt; for (i = 0; ;i++) {&lt;br /&gt;   if (x[i] == t)&lt;br /&gt;     break;&lt;br /&gt; x[n] = hold;&lt;br /&gt; if (i == n)&lt;br /&gt;   return -1;&lt;br /&gt; else&lt;br /&gt;   return i;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;요렇게 해서 for 루프에서 매번하던 비교연산을 줄일 수 있다.&lt;br /&gt;&lt;br /&gt;그리고, &lt;span style="font-weight: bold;"&gt;loop unrolling으로 속도를 개선할 수 있다.&lt;/span&gt; loop를 말그대로 조금 펼쳐서 pipeline이나 Multicore 에서 돌아가는 점을 살려 병렬로 실행시킬 수 있다. (요건 컴파일러에서도 어느정도 지원해줄 것 같다.)&lt;br /&gt;&lt;br /&gt;위에서 소개된 방법들의 이름으로 정리를 해보면,&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Exploit common cases&lt;/span&gt; 자주쓰이는 경우를 캐시하는 것과 비슷한 방법이고,&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Exploit an algebric identity&lt;/span&gt; 요건 대수적인 최적화를 한다는 것이고,&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Collapsing procedure hierarchy&lt;/span&gt; 는 함수콜 대신 매크로, 인라인 쓰는 것이고&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Loop unrolling&lt;/span&gt; 은 아까 했고.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Data structure augmentation&lt;/span&gt; 은,. 설명하기 귀찮다. ㅡ.ㅡ;.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-386170039923299981?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/386170039923299981/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/10/code-tuning.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/386170039923299981'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/386170039923299981'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/10/code-tuning.html' title='Code Tuning'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-80432929422745996</id><published>2008-10-10T23:00:00.003+09:00</published><updated>2008-10-10T23:14:18.455+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='algorithm'/><title type='text'>Dijkstra Algorithm</title><content type='html'>다익스트라 알고리즘은 가중치를 가지는 양방향 그래프에서 특정 정점에 대한 나머지 정점들로의 최단거리를 구하는 알고리즘이다.&lt;br /&gt;가중치를 가지는 간선을 가지는 그래프를 G[V,E] 라하고 정점들의 집합을 S, Q두개로 가질 수 있다고 할때 알고리즘은 아래와 같이 기술될 수 있다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;while Q is not empty&lt;br /&gt; S = empty&lt;br /&gt; Q = G[V,E]&lt;br /&gt; u = extract_min(Q);&lt;br /&gt; for edge from u&lt;br /&gt;   relax(edge, u)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;간단히 기술하면, 먼저 시작점 s 로부터 걸리는 경로 값을 각 정점에 기록할 수 있다고 할때, 모든 정점에 infinite 값 (아주 큰값)을 넣은 후 모든 정점들을 Q에 넣는다(s 에는 값 0을 넣는다). 그리고 Q 에서 최소 값을 가지는 정점을 하나 꺼내어 이 정점이 가지는 모든 간선들에 대해 relax를 수행한다. relax 란 간선들과 연결된 정점들에 최단 경로값을 갱신해 넣어주는 것을 말한다(이미 Q에서 빠져나온 노드들에 대해서도 갱신한다). 이 과정을 Q에 정점이 없을 때까지 반복한다.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-80432929422745996?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/80432929422745996/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/10/dijkstra-algorithm.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/80432929422745996'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/80432929422745996'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/10/dijkstra-algorithm.html' title='Dijkstra Algorithm'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-231526054703197390</id><published>2008-08-28T14:24:00.003+09:00</published><updated>2008-08-28T14:28:13.962+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Collective Intelligence'/><title type='text'>Collaborative Filtering</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Collaborative Filtering&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;유사한 취향을 가진 사람들의 작은 집합을 만드는 것. 일종의 클러스터링.&lt;br /&gt;&lt;br /&gt;관련 논문으로 "Using collaborative filtering to weave an information tapestry" 이 있음.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Similarity score 계산&lt;/span&gt;&lt;br /&gt;사람(혹은 아이템) 간의 취향이 얼마나 비슷한지 정도를 계산할 수 있는데, 아래의 방법들이 있음&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Euclidean distance score&lt;/span&gt;&lt;br /&gt;각각의 항목들을 축으로 놓고 특정 사람에 대한 항목별 선호도를 점으로 표시하면 두사람간의 거리를 계산하여 유사도를 구할 수 있는데 이를 유클리디안 거리점수 라고 한다. 항목이 두개 (x, y)인 경우 두 사람 A(x1, y1), B(x2, y2) 간의 거리는 y = sqrt( (x1 - x2)^2 + (y1 - y2)^2 ) 이다. 마찬가지로 n 개의 항목에 대한 유클리디안 거리점수를 계산하면 아래처럼 표시될 수 있다.&lt;br /&gt;&lt;br /&gt;y = sqrt( (a1 - a2)^2 + ... + (n1 - n2)^2 )&lt;br /&gt;&lt;br /&gt;일반적으로 이렇게 구한 거리 d 를 1/d식으로 활용하여 서로 유사할 수록 높은 점수를 주는 방식으로 사용한다.&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Pearson correlation score&lt;/span&gt;&lt;br /&gt;두개의 데이처 집합이 한 직선으로 잘 표현되는 정도를 나타낸 것이 상관계수인데, 정규화되지 않은 데이터에 대해 좋은 결과를 제공한다. 각각의 값이 점으로 표시된 좌표에서 모든 점들과 가장 가까운 직선을 그릴 수 있는데 이를 최적맞춤선(best-fit line)이라고 한다. 여러 항목들에 대한 두사람의 선호도 데이터를 가지고 있다면 이 두사람을 각 좌표의 축에 놓고 best-fit line을 그릴 수 있다.&lt;br /&gt;이 직선을 통해서 대체적으로 누가 더 많은 점수를 주었는지를 파악할 수도 있는데, 이를 grade inflation이라고 한다. 한쪽이 더 높은 점수를 꾸준하게 주었어도 선호도가 비슷하다면 직선으로 잘 표현될 수도 있다.&lt;br /&gt;때문에 Euclidean distance에서는 한쪽이 전체적으로 낮은 점수를 주었으면 두 사람의 유사도가 낮게 나오는 반면 Pearson correlation score에서는 이를 유사한 것으로 뽑아낼 수 있다.&lt;br /&gt;아래의 두 사람의 데이터에 대한 Pearson correlation score를 뽑아낸다고 하면,&lt;br /&gt;&lt;br /&gt;m1[] = { a1, a2, ... , an}&lt;br /&gt;m2[] = { b1, b2, ... , bn}&lt;br /&gt;&lt;br /&gt;아래와 같은 식으로 상관계수 값을 도출할 수 있다.&lt;br /&gt;&lt;br /&gt;sum1 = a1 + ... + an&lt;br /&gt;sum2 = b1 + ... + bn&lt;br /&gt;&lt;br /&gt;sq_sum1 = a1^2 + ... + an^2&lt;br /&gt;sq_sum2 = b1^2 + ... + bn^2&lt;br /&gt;&lt;br /&gt;mul_sum = a1 * b1 + ... + an * bn&lt;br /&gt;&lt;br /&gt;v1 = mul_sum - (sum1 * sum2 / n)&lt;br /&gt;v2 = sqrt( (sq_sum1 - (sum1^2) / n) * (sq_sum2 - (sum^2) / n) )&lt;br /&gt;&lt;br /&gt;return v2 == 0 ? 0 : n / v2&lt;br /&gt;&lt;br /&gt;값은 -1 ~ 1 사이이고 1은 모든 항목에 같은 점수를 준 것이다.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-231526054703197390?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/231526054703197390/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/08/collaborative-filtering.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/231526054703197390'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/231526054703197390'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/08/collaborative-filtering.html' title='Collaborative Filtering'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-2335999646619421574</id><published>2008-08-21T00:41:00.002+09:00</published><updated>2008-08-21T00:44:45.141+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Misc'/><title type='text'>Const pointer &amp; pointer const</title><content type='html'>const pointer refers const variable.&lt;br /&gt;&lt;br /&gt;pointer const refers variable constantly(Setting it to point another variable is not possible).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-2335999646619421574?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/2335999646619421574/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/08/const-pointer-pointer-const.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/2335999646619421574'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/2335999646619421574'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/08/const-pointer-pointer-const.html' title='Const pointer &amp; pointer const'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-2127341961470814523</id><published>2008-08-13T10:38:00.004+09:00</published><updated>2008-08-13T10:49:58.878+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>Advanced Generic Handle - Copy On Write</title><content type='html'>Generic Handle Class는 여러 클래스를 동일하게 다룰 수 있지만 메모리 복사가 많이 일어나는 오버헤드가 있다. Reference Count를 사용한 Generic Handle Class는 값을 항상 참조만 시키기 때문에 s2 = s1 처럼 대입하면 s2의 값을 바꾸었을때 s1의 값이 항상 바뀐다(같은 객체를 참조하니까). 때문에 경우에 따라 참조하고, 경우에 따라 복사를 하는 더 나은 형태의 Generic Handle Class 가 있으면 좋겠다.&lt;br /&gt;&lt;br /&gt;즉, s3 = s2 = s1처럼 대입하면 실제 복사는 일어나지 않고 s3, s2가 s1의 레퍼런스만 가지고 있게 하다가, s3에 다른 새로운 값을 대입하거나 내부 멤버를 변경하는 작업이 일어날 때 비로소 s1의 멤버 값들을 복사한 후 s1에 대한 레퍼런스를 끊어 별개의 객체로 동작하게 하는 것이다.&lt;br /&gt;&lt;br /&gt;linux memory management의 COW(Copy-On-Write)처럼 변경 사항이 일어날 때 비로소 복사를 하는 것이다.&lt;br /&gt;&lt;br /&gt;실제 이러한 클래스를 구현하는 방법은 기존의 Reference Count를 사용하는 Generic Handle Class에 아래와 같이 reference count를 체크한 후 복사를 진행하는 멤버 함수를 추가한 후, 멤버를 변경시키는 함수 호출시 이 멤버함수를 실행시키면 된다.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;template&lt;class T&gt; class Ptr {&lt;br /&gt;    public:&lt;br /&gt;        void make_uniue() {&lt;br /&gt;            if (*refptr != 1) {&lt;br /&gt;                --*refptr;&lt;br /&gt;                refptr = new size_t(1);&lt;br /&gt;                p = p ? p-&gt;clone() : 0;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-2127341961470814523?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/2127341961470814523/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/08/advanced-generic-handle-copy-on-write.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/2127341961470814523'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/2127341961470814523'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/08/advanced-generic-handle-copy-on-write.html' title='Advanced Generic Handle - Copy On Write'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-4426149018338324310</id><published>2008-08-13T09:46:00.002+09:00</published><updated>2008-08-13T10:38:22.009+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>Advanced Generic Handle - Reference Count</title><content type='html'>Generic Handle Class를 만들어 사용하게 되면 대입 연산과 같은 여러 작업을 진행할 때 불필요한 메모리 복사가 많이 일어나 오버헤드가 된다. 값을 읽기만 하기 위해 대입하는 경우 값을 복사하지 않고 레퍼런스만 넘겨주면 이를 줄일 수 있는데, 핸들 클래스를 통해 참조되는 값들은 동적으로 생성된 것들이기 때문에 해제를 하려면 자신을 참조하고 있는 객체가 몇개인지 확인해 보고 참조하고 있는 값이 없을 때 해제하면 된다.&lt;br /&gt;&lt;br /&gt;이를 위해 제네릭 핸들 클래스에서 사용하는 방식이 reference count다. 복사나 대입 연산이 발생하는 경우 핸들 클래스에서 가지고 있는 reference count를 증가시키고 반대의 경우 감소시키는 방식으로 카운터를 유지하다가 레퍼런스가 없게 될 때 최종적으로 소멸시키게 된다.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-4426149018338324310?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/4426149018338324310/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/08/advanced-generic-handle-reference-count.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/4426149018338324310'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/4426149018338324310'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/08/advanced-generic-handle-reference-count.html' title='Advanced Generic Handle - Reference Count'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-6966629813825166013</id><published>2008-08-12T09:25:00.008+09:00</published><updated>2008-08-12T09:40:07.646+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>Generic Handle Class</title><content type='html'>Handle Class는 기본 클래스에서 파생된 여러 클래스를 레퍼런스나 포인터를 통해 모두 다룰 수 있도록 캡슐화 해준다. 제대로 짠다면 이러한 Handle Class는 다루는 클래스에 대해 최대한 독립적이여야 한다. 그래서 다루는 클래스 자체를 탬플릿으로 선언하여 Handle Class를 구현하는데 이를 Generic Handle Class라고 한다.&lt;br /&gt;&lt;br /&gt;핸들을 사용하기 않고 직접 저수준의 포인터를 사용하게 될 경우 아래와 같은 잠재적인 문제가 있다.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;포인터 복사만 하면 객체는 복사가 안된다.&lt;/li&gt;&lt;li&gt;포인터 소멸시켜도 객체는 소멸 안된다.&lt;/li&gt;&lt;li&gt;반대로 포인터를 두고 객체만 소멸시키면 Dangling Pointer가 된다.&lt;/li&gt;&lt;li&gt;포인터 만들고 바인딩 안하고 쓰면 ... 알 수 없는 동작을 한다.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Generic Handle Class는 기본적으로 아래와 같은 기능을 제공한다.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Handle을 특정 객체를 참조하는 값으로 생각하면 된다.&lt;/li&gt;&lt;li&gt;객체를 복사할 수 있다(복사 생성자, 대입연산자).&lt;/li&gt;&lt;li&gt;바인딩 여부를 알 수 있다(bool() 연산을 정의하면 됨).&lt;/li&gt;&lt;li&gt;virtual 함수 호출을 통해 각 클래스별 메소드를 호출할 수 있다.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;우리가 직접 포인터/레퍼런스를 쓰지 않고 핸들 클래스를 사용하기로 했기 때문에 당연히 이후부터는 객체를 포인터를 통해 직접 접근하면 안된다. 그리고 메모리 관리도 Handle Class에서 자동으로 해주므로 Handle을 소멸시키면 Handle에 연결된 객체도 같이 소멸된다.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;template&amp;lt;class T&amp;gt; class Handle {&lt;br /&gt; public:&lt;br /&gt;     Handle() : p(0) { }&lt;br /&gt;     Handle(const Handle&amp;amp; s) : p(0) { if(s.p) p = s.p-&amp;gt;clone(); }&lt;br /&gt;     Handle&amp;amp; operator=(const Handle&amp;amp;);&lt;br /&gt;     ~Handle() { delete p; }&lt;br /&gt;&lt;br /&gt;     Handle(T* t) : p(t) { }&lt;br /&gt;&lt;br /&gt;     operator bool() const { return p; }&lt;br /&gt;     T&amp;amp; operator*() const;&lt;br /&gt;     T* operator-&amp;gt;() const;&lt;br /&gt;&lt;br /&gt; private:&lt;br /&gt;     T* p;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;template&amp;lt;class T&amp;gt;&lt;br /&gt;Handle&amp;lt;T&amp;gt;&amp;amp; Handle&amp;lt;T&amp;gt;::operator=(const Handle&amp;amp; rhs)&lt;br /&gt;&lt;br /&gt; if (&amp;amp;rhs != this) {&lt;br /&gt;     delete p;&lt;br /&gt;     p = rhs.p ? rhs.p-&amp;gt;clone() : 0;&lt;br /&gt; }&lt;br /&gt; return *this;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;template&amp;lt;class T&amp;gt;&lt;br /&gt;T&amp;amp; Handle&amp;lt;T&amp;gt;::operator*() const&lt;br /&gt;{&lt;br /&gt; if (p)&lt;br /&gt;     return *p;&lt;br /&gt; throw runtime_error("unbound Handle");&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;template&amp;lt;class T&amp;gt;&lt;br /&gt;T* Handle&amp;lt;T&amp;gt;::operator-&amp;gt;() const&lt;br /&gt;{&lt;br /&gt; if (p)&lt;br /&gt;     return p;&lt;br /&gt; throw runtime_error("unbound Handle");&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;A를 B가 상속받은 경우, Handle &amp;lt;A&amp;gt; h(new B); 식으로 핸들을 생성하면 B클래스가 생성되어 핸들클래스의 포인터에 바인딩된다(virtual 함수를 사용할 수 있다).&lt;br /&gt;&lt;br /&gt;operator* 를 정의하므로써 핸들이 가지고 있는 클래스 포인터로 클래스 레퍼런스를 반환하는 역할을 한다.&lt;br /&gt;&lt;br /&gt;operator-&gt;는 이항연산자 인줄 알았는데 아니란다 ㅡ.ㅡ; 단지 이걸 통해서 오른쪽에 있는 멤버를 접근할 수 있게 해준덴다. 즉, x-&gt;y 인 경우 (x.operator-&gt;())-&gt;y 나 x.p-&gt;y와 같덴다. 요건 좀 비직관적인 듯하다.&lt;br /&gt;&lt;br /&gt;아무튼 이 두 연산을 통해 Dynamic Binding이 가능해진다. 앗싸.&lt;br /&gt;&lt;br /&gt;나는 generic handle class를 만들면 handle class가 필요없는 줄 알았다. Accelerated C++의 내용을 대강 정리해서 어쩌다 제네릭 핸들 클래스를 만들게 되었는지 요약해보면 아래와 같다.&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;클래스를 만들었다.&lt;/li&gt;&lt;li&gt;비슷하지만 다른 클래스도 필요하게 되었다.&lt;/li&gt;&lt;li&gt;두 클래스를 하나의 코드로 다룰려고 dynamic binding을 사용하려니 포인터/레퍼런스 사용이 복잡하다.&lt;/li&gt;&lt;li&gt;그래서 두 클래스를 사용하는 핸들 클래스를 만들고 이 핸들을 사용하기로 했다.&lt;/li&gt;&lt;li&gt;근데 핸들 클래스에도 포인터를 사용하려니 짜증난다.&lt;/li&gt;&lt;li&gt;포인터를 사용하는 부분만 제네릭 핸들 클래스로 빼버렸다.&lt;/li&gt;&lt;li&gt;결국 두 클래스 -&gt; 제네릭 핸들 클래스 -&gt; 핸들 클래스 -&gt; 일반 코드 식으로 접근하도록 하여구현하게 되었다.&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-6966629813825166013?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/6966629813825166013/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/08/generic-handle-class.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/6966629813825166013'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/6966629813825166013'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/08/generic-handle-class.html' title='Generic Handle Class'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-2565208731942927895</id><published>2008-08-11T11:52:00.003+09:00</published><updated>2008-08-11T12:01:32.630+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>Basic concepts</title><content type='html'>&lt;span style="font-weight: bold;"&gt;상속&lt;/span&gt;&lt;br /&gt;class drivedClass : public baseClass { ... }&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;public&lt;/span&gt;&lt;br /&gt;interface의 일부로 상속한다는 의미 not as an implementation&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;protected&lt;/span&gt;&lt;br /&gt;기본 클래스의 private멤버에 접근하고 싶을때 protected에 선언&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;baseClass::function&lt;/span&gt;&lt;br /&gt;같은 이름의 기본클래스의 함수에 접근하고 싶을때&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Polymorphism(다형성), binding&lt;/span&gt;&lt;br /&gt;기본클래스의 레퍼런스를 인자로 받는 함수에서 파생클래스를 넣어도 되는 식&lt;br /&gt;- 파생클래스의 기본 클래스 부분만 사용된다. (1)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;virtual&lt;/span&gt;&lt;br /&gt;(1)에서 파생클래스의 것을 자동으로 사용하게 해주고 싶을때 사용&lt;br /&gt;클래스의 인자가 레퍼런스나 포인터로 호출된 경우에만 가능.&lt;br /&gt;&lt;br /&gt;일반적으로 파생클래스에서 재정의 되는 virtual함수들은 기본클래스의 함수와 동일한 타입을 리턴해야하지만, 기본클래스의 virtual함수가 *this를 리턴하는 경우 파생클래스에서도 기본클래스의 포인터가아닌 파생클래스의 포인터(*this)를 리턴할 수 있다.&lt;br /&gt;&lt;br /&gt;virtual function의 경우 기본/파생 클래스 함수들의 매개변수 갯수 타입이 다르면 별도의 함수로 동작하기 때문에 이를 고려해서 구현해야한다. 매개변수 개수가 다른 경우에는 아래와 같은 식의 구현을 통해 virtual function을 사용할 수 있다.&lt;br /&gt;&lt;br /&gt;void BaseClass::func(double d1, double = 0) { ... }&lt;br /&gt;void DerivedClass::func(double d1, double d2) { ... }&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;static binding&lt;/span&gt;&lt;br /&gt;호출되기 전에 타입이 결정되어 그 타입으로 사용됨&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;dynamic binding&lt;/span&gt;&lt;br /&gt;호출될 때 타입이 결정되어 그 타입으로 사용됨&lt;br /&gt;레퍼런스나 포인터로 전달할 때 이루어짐 (실제 전달되는 값을 알지 못하므로)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;virtual destructor&lt;/span&gt;&lt;br /&gt;포인터나 레퍼런스에 대한 객체의 타입을 모르지만 delete 하고 싶은 경우 소멸자를 virtual로 선언하여 각 객체에 맞는 소멸자를 호출해주게 하는 것&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Rule of three&lt;/span&gt;&lt;br /&gt;복사생성자, 대입연산자, 소멸자 : 는 붙어 다닌다.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;static member function&lt;/span&gt;&lt;br /&gt;클래스의 멤버 함수로 호출되더라도 객체(this)의 멤버와 연관이 없는 작업을 수행하는 함수.&lt;br /&gt;ex. static void func (classA&amp;amp; c1, classA&amp;amp; c2)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;handle class&lt;/span&gt;&lt;br /&gt;서로 상속관계를 가진 여러 클래스들을 하나의 클래스 처럼 사용하고자 할 때 인터페이스 역할을 하도록 하나의 클래스를 만들어 각 경우에 맞는 클래스의 객체를 생성하고 생성한 객체의 포인터(혹은 레퍼런스)를 가지게 하는데, 이를 핸들 클래스 라고 한다. 이 때 포인터는 기본클래스의 포인터를 가진다.&lt;br /&gt;포인터를 가지고 연산하기 때문에 복사생성자, 대입연산자, 소멸자가 필요하다.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;virtual clone function&lt;/span&gt;&lt;br /&gt;복사 생성자의 경우, 핸들클래스는 생성한 클래스의 포인터를 가지고 있기 때문에 어떤 클래스를 생성해서 가지고 있는지 모르므로, 복사될 핸들 클래스의 포인터에 어떤 클래스를 생성해서 대입해야할지 모른다. 그래서 자기 자신을 복사하는 clone 함수를 각 클래스 별로 정의하고, 기본클래스에서 이를 virtual 로 선언해서 핸들 클래스에서 사용시에 각 타입에 맞는 방식의 clone함수를&lt;br /&gt;사용해 복사후 핸들클래스의 포인터로 넘겨줄 수 있다.&lt;br /&gt;&lt;br /&gt;ex. 대부분 각 클래스들은 아래와 같은 식으로 clone()을 만들어 놓는다.&lt;br /&gt;protected:&lt;br /&gt;// virtual 은 기본클래스의 경우에만.&lt;br /&gt;virtual BaseClass* clone() const { return new BaseClass(*this); }&lt;br /&gt;&lt;br /&gt;대신 핸들클래스가 이를 사용할 수 있도록 기본클래스의 friend로 등록되어야 한다.&lt;br /&gt;&lt;br /&gt;핸들 클래스에서 기본클래스의 포인터를 가지고 있기 때문에 파생클래스의 clone에 대한 접근은 virtual call로 이루어 진다. 때문에 핸들클래스만 기본클래스의 friend 로 등록되면 된다.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;friend&lt;/span&gt;&lt;br /&gt;함수가 특정 클래스의 protected영역에 접근할 수 있도록 할 때 클래스에 이 함수를 friend로 등록할 수 있다. 클래스가 friend로 등록된 경우 클래스의 모든 멤버가 대상 클래스의 friend 가 된다.&lt;br /&gt;&lt;br /&gt;friend관계는 상속되지 않는다.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-2565208731942927895?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/2565208731942927895/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/08/basic-concepts.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/2565208731942927895'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/2565208731942927895'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/08/basic-concepts.html' title='Basic concepts'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-8532699301834883023</id><published>2008-06-24T09:40:00.004+09:00</published><updated>2008-06-25T09:51:09.584+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='network'/><title type='text'>Utility functions</title><content type='html'>&lt;pre&gt;&lt;br /&gt;&lt;span style="color: rgb(46, 139, 87);"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/span&gt; hostent {&lt;br /&gt;      &lt;span style="color: rgb(46, 139, 87);"&gt;&lt;b&gt;char&lt;/b&gt;&lt;/span&gt;   *h_name;&lt;br /&gt;      &lt;span style="color: rgb(46, 139, 87);"&gt;&lt;b&gt;char&lt;/b&gt;&lt;/span&gt;   **h_aliases;&lt;br /&gt;      &lt;span style="color: rgb(46, 139, 87);"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/span&gt;    h_addrtype;     &lt;span style="color: rgb(0, 0, 255);"&gt;/*&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt; AF_INET &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;*/&lt;/span&gt;&lt;br /&gt;      &lt;span style="color: rgb(46, 139, 87);"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/span&gt;    h_length;       &lt;span style="color: rgb(0, 0, 255);"&gt;/*&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt; h_addr_list length &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;*/&lt;/span&gt;&lt;br /&gt;      &lt;span style="color: rgb(46, 139, 87);"&gt;&lt;b&gt;char&lt;/b&gt;&lt;/span&gt;   **h_addr_list;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;위 hostent의 h_addr_list는 network byte order로 된 in_addr인데, h_addr_list는 char ** 이므로, 이를 실제로 사용할 때는 inet_ntoa(*(int *)h_addr_list[i]) 식으로 하면 4byte를 읽어 inet_ntoa에 넣게 되므로 값을 확인해볼 수 있다. 아래는 각 함수별 설명이다.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;gethostbyname(...)&lt;/span&gt; 은 호스트 이름으로 hostent 를 가지고 오는 함수이다.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;gethostbyaddr(...)&lt;/span&gt; 는 IP주소로 hostent를 가지고 오는 함수이다&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;getsockopt(...), setsockopt(...)&lt;/span&gt; 는 소켓 옵션 관련 함수이고, 앞에서 했고,..&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;getsockname(...)&lt;/span&gt; 은 bind된 sockaddr 정보를 얻어오는 함수이다 (자동 할당된 포트 번호 확인 시 사용)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;getpeername(...)&lt;/span&gt; 은 반대로 연결된 상대편의 sockaddr정보를 얻어오는 함수이다&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;getservent(), getservbyname(), getservbyport()&lt;/span&gt; 함수들은 /etc/services파일을 가져오는 함수들이다(전체 다 가져오거나, 서비스 이름으로 찾거나, 포트 번호로 찾는 함수)&lt;br/&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;getprotoent(), getprotobyname(), getprotobynumber()&lt;/span&gt; 역시 마찬가지로 /etc/protocols 파일을 가져오는 함수들이다.&lt;br/&gt;&lt;br /&gt;&lt;br /&gt;위 두그룹들은 각각 serverent, protoent 구조체를 알아야 한다.&lt;br/&gt;&lt;br /&gt;&lt;br /&gt;주소변환 함수 그룹들은 지난번에 기록한것 같은데 이름만 다시 정리하면, inet_addr/inet_aton, inet_pton, inet_ntoa, inet_ntop 이다. pton, aton의 차이는 리턴되는 값을 static공간에 담아주냐 아니냐의 문제인데, reentrant를 고려하여 제공되는 함수가 pton, ntop 군이니 필요할 때 구별해서 쓰면된다.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-8532699301834883023?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/8532699301834883023/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/06/utility-functions.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/8532699301834883023'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/8532699301834883023'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/06/utility-functions.html' title='Utility functions'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-3716197636888977105</id><published>2008-06-24T09:13:00.003+09:00</published><updated>2008-06-24T09:39:43.155+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='network'/><title type='text'>Socket, options</title><content type='html'>소켓 사용시 여러 옵션을 줄 수 있는데, 아래 함수를 통해 set, get이 가능하다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span style="color:#2e8b57;"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/span&gt; getsockopt(&lt;span style="color:#2e8b57;"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/span&gt; s, &lt;span style="color:#2e8b57;"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/span&gt; level, &lt;span style="color:#2e8b57;"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/span&gt; optname, &lt;span style="color:#2e8b57;"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/span&gt; *optval, socklen_t *optlen);&lt;br /&gt;&lt;span style="color:#2e8b57;"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/span&gt; setsockopt(&lt;span style="color:#2e8b57;"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/span&gt; s, &lt;span style="color:#2e8b57;"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/span&gt; level, &lt;span style="color:#2e8b57;"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/span&gt; optname, &lt;span style="color:#2e8b57;"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/span&gt; *optval, socklen_t *optlen);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;설정할 수 있는 옵션은 영역이 매우 다양한데(이를 테면, TCP에서의 옵션이라던가, IP레이어에서의 옵션이라던가 등...), 어느 영역에서의 옵션을 설정할 것인지를 두번째 인자인 level에서 선택할 수 있다. 몇개의 옵션들은 아래와 같다.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;SOL_SOCKET&lt;/li&gt;&lt;ul&gt;&lt;li&gt;SO_BROADCAST&lt;/li&gt;&lt;li&gt;SO_REUSEADDR&lt;/li&gt;&lt;ul&gt;&lt;li&gt;TCP의 TIME_WAIT상태의 소켓을 다시 재사용할 수 있게 해주는 옵션으로 서버쪽에서 active close해서 TIME_WAIT상태로 빠지면 이 시간동안 listen이 실패하므로, 바로 listen할 수 있도록 TIME_WAIT상태에서소 소켓을 사용할 수 있도록 하기 위해 사용한다.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;SO_LINGER&lt;/li&gt;&lt;ul&gt;&lt;li&gt;struct linger { int l_onoff; int l_linger; } 를 사용한다.&lt;/li&gt;&lt;li&gt;데이터를 전송 후 끊기 위해 기다리는 시간을 l_linger에 지정할수 있는데, 0인경우 버퍼를 없에버리고 바로 close하며 client 쪽에도 RST를 보내서 TIME_WAIT되지 않고 바로 끊도록 한다. (aborty shutdown, aborty close. 0이 아닌 경우라면 graceful close/shutdown)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;SO_KEEPALIVE&lt;/li&gt;&lt;ul&gt;&lt;li&gt;일정시간마다 연결상태 확인&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;SO_OOBINLINE&lt;/li&gt;&lt;li&gt;SO_RCVBUF&lt;/li&gt;&lt;ul&gt;&lt;li&gt;수신 버퍼크기 조정(실제로는 지정한 값의 두배가 잡힘). 자동으로 조정되는 경우에는 설정할 수 없는 경우도 있음&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;SO_SNDBUF&lt;/li&gt;&lt;li&gt;SO_RCVTIMEO&lt;/li&gt;&lt;ul&gt;&lt;li&gt;blocking 함수를 사용하는 경우(recv, ...) block에서 깨어날 시간을 지정할 수 있음. timeval로 지정하면 됨. timeout으로 빠져나오면 -1이 리턴되고, errno가 EAGAIN이 됨 (아래 SNDTIMEO도 마찬가지)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;SO_SNDTIMEO&lt;/li&gt;&lt;li&gt;SO_RCVLOWAT&lt;/li&gt;&lt;ul&gt;&lt;li&gt;watermark인데 I/O를 발생할 최소단위의 크기를 지정한다. default로 1이다.  (버전에 따라 지원정도가 다르다)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;SO_SNDLOWAT&lt;/li&gt;&lt;li&gt;SO_TYPE&lt;/li&gt;&lt;li&gt;SO_ERROR&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;IPPROTO_IP&lt;/li&gt;&lt;ul&gt;&lt;li&gt;IP_TTL&lt;/li&gt;&lt;li&gt;IP_MULTICAST_TTL&lt;/li&gt;&lt;li&gt;IP_ADD_MEMBERSHIP&lt;/li&gt;&lt;li&gt;IP_DROP_MEMBERSHIP&lt;/li&gt;&lt;li&gt;IP_MULTICAST_LOOP&lt;/li&gt;&lt;li&gt;IP_MULTICAST_IF&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;IPPROTO_TCP&lt;/li&gt;&lt;ul&gt;&lt;li&gt;TCP_NODELAY&lt;/li&gt;&lt;ul&gt;&lt;li&gt;1이면 Nagle Algorithm을 사용안함&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;TCP_MAXSEG&lt;/li&gt;&lt;ul&gt;&lt;li&gt;MSS크기 조절함(잘못 조절하면 ,... ㅡ.ㅡ;)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-3716197636888977105?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/3716197636888977105/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/06/socket-options.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/3716197636888977105'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/3716197636888977105'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/06/socket-options.html' title='Socket, options'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-2846600155207209860</id><published>2008-06-24T09:07:00.005+09:00</published><updated>2008-06-24T09:13:48.356+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='network'/><title type='text'>UDP Broadcasting</title><content type='html'>매우 간단하다. 소켓 옵션에 SO_BROADCAST를 주고 수신측 주소에 INADDR_BROADCAST를 주면된다. 특정 네트웍으로 broadcast하고 싶으면 해당 네트웍 주소를 주면된다. 소켓 옵션에 값을 줄때는 아래처럼 setsockopt를 사용한다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; sockopt = &lt;font color="#ff00ff"&gt;1&lt;/font&gt;;&lt;br /&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt; (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &amp;amp;sockopt, &lt;font color="#a52a2a"&gt;&lt;b&gt;sizeof&lt;/b&gt;&lt;/font&gt;(sockopt)) == -&lt;font color="#ff00ff"&gt;1&lt;/font&gt;) {&lt;br /&gt;&lt;font color="#0000ff"&gt;/*&lt;/font&gt;&lt;font color="#0000ff"&gt; Handle error &lt;/font&gt;&lt;font color="#0000ff"&gt;*/&lt;/font&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-2846600155207209860?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/2846600155207209860/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/06/udp-broadcasting.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/2846600155207209860'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/2846600155207209860'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/06/udp-broadcasting.html' title='UDP Broadcasting'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-419555872886758959</id><published>2008-06-24T09:07:00.002+09:00</published><updated>2008-06-24T09:07:46.318+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='network'/><title type='text'>TCP Options</title><content type='html'>TCP의 성능 향상을 위해 사용되는 여러가지 방법들을 정리해보자.&lt;br/&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;TCP autotuning&lt;/span&gt;은 소켓 버퍼의 크기를 동적으로 조절하는 기능인데, 2.6.8커널 이후 버전에서 지원되며, 아래 값들을 통해 설정할 수 있다.&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;net.ipv4.tcp_moderate_rcvbuf : 수신쪽의 autotuning 설정&lt;/li&gt;&lt;br /&gt;&lt;li&gt;net.ipv4.tcprmem : 수신 버퍼의 최소/기본/최대값 (송신쪽은 ...wmem)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;net.core.rmem_max : 지정할 수 있는 수신 버퍼 크기의 최대값 (송신쪽은 wmem)&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;값들은 sysctl 커멘드로 확인할 수 있다. &lt;br/&gt;&lt;br /&gt;그외, TCP timestamp 는 RTT 측정 오차를 줄이는 방법이고. WSCALE이라고 16bit로 제한된 윈도우 사이즈를 늘려주는 옵션이다.&lt;br/&gt;&lt;br /&gt;그리고.. 여러개의 패킷 유실에 대해 ACK를 개별적으로 보내주는 selective ack도 있다.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-419555872886758959?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/419555872886758959/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/06/imsi.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/419555872886758959'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/419555872886758959'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/06/imsi.html' title='TCP Options'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-6127050691917207594</id><published>2008-06-23T09:29:00.003+09:00</published><updated>2008-06-23T09:38:14.376+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='network'/><title type='text'>TCP vs UDP</title><content type='html'>ALSP 책에서는 segment와 fragmentation을 구별하여 정의하고 있다. 둘다 데이터를 분할하는 것이지만 후자는 재결합이 가능하도록 쪼개는 것이고, 전자는 재결합과는 상관없이 데이터를 쪼개는 행위 자체를 말한다. TCP에서는 IP레이어로 내려가기 전에 segment 단위로 데이터를 쪼개는데, 이때 사용되는 크기가 MSS(Maximum Segment Size)이다. TCP에서는 이렇게 미리 데이터가 분할되어 내려오기 때문에 나중에 MTU 사이즈에 의해 재 분할 되지 않으며, UDP의 경우 IP레이어에서 MTU사이즈로 분할 된다.&lt;br/&gt;&lt;br /&gt;TCP는 그 이름이 Transmission Control Protocol인 것처럼 헤더에 제어 flag이 붙는데, 이들은 URG, ACK, PSG, RST, SYN, FIN 으로 구성되어 있다.&lt;br/&gt;&lt;br /&gt;UDP의 경우는 별도의 control flag 이 없어서 단순하게 사용 가능하나, 전송하는 데이터그램이 버퍼크기보다 작아야 함을 주의해야 한다. 버퍼보다 큰 데이터그램이 들어오는 경우 Drop되기 때문이다. 이것은 netstat -s 로 UDP overflow가 있는지 확인해 보므로써 알 수 있다.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-6127050691917207594?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/6127050691917207594/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/06/tcp-vs-udp.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/6127050691917207594'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/6127050691917207594'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/06/tcp-vs-udp.html' title='TCP vs UDP'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-4899188566402118336</id><published>2008-06-23T09:11:00.002+09:00</published><updated>2008-06-23T09:29:02.210+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='network'/><title type='text'>UDP</title><content type='html'>UDP는 별도의 연결 과정이 없다. 때문에 매번 보낼때 송수신 주소를 담아서 보내고 받는다. 그리고 broadcast, multicast 식으로 한번에 여러 곳으로 데이터를 송신할 수 있다. 일단 bind()로 바인딩 후 sendto(), recvfrom()으로 주고 받는다. 송수신이 완료되면 close(), shutdown()으로 소켓을 닫는다. 연결이 없어서 server, client 구분이 없다. 간단하다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; sendto (&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; s, &lt;font color="#2e8b57"&gt;&lt;b&gt;const&lt;/b&gt;&lt;/font&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; *msg, &lt;font color="#2e8b57"&gt;&lt;b&gt;size_t&lt;/b&gt;&lt;/font&gt; len, &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; flags, &lt;font color="#2e8b57"&gt;&lt;b&gt;const&lt;/b&gt;&lt;/font&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; sockaddr *to, socklen_t tolen);&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; recvfrom(&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; s, &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; *buf, &lt;font color="#2e8b57"&gt;&lt;b&gt;size_t&lt;/b&gt;&lt;/font&gt; len, &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; flags, &lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; sockaddr *from, socklen_t *fromlen);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;인자는, 뭐 대충,.. 소켓, 데이터, 데이터길이, 옵션, 송(수)신 주소, 주소 길이.. 식이다.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-4899188566402118336?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/4899188566402118336/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/06/udp.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/4899188566402118336'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/4899188566402118336'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/06/udp.html' title='UDP'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-475344546487695194</id><published>2008-06-20T09:08:00.003+09:00</published><updated>2008-06-20T09:42:36.141+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='network'/><category scheme='http://www.blogger.com/atom/ns#' term='socket'/><title type='text'>TCP Status</title><content type='html'>TCP연결시에는 알다시피 3way handshaking을 한다. close시에는 client, server 가 각각 FIN을 보낸 후 ACK를 받는다(총 4번의 트랜젝션).&lt;br/&gt;&lt;br /&gt;TCP연결에는 여러개의 상태가 있는데, netstat으로 확인할 수 있는 상태들에 대해 간단히 정리해보면,&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;서버에서 listen()이 호출되면 상태는 LISTEN으로 바뀐다.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;이 때 client에서 SYN을 보낸 후 SYN_SENT로 상태가 바뀌면&lt;/li&gt;&lt;br /&gt;&lt;li&gt;서버에서 이를 받고 SYN_RCVD로 바뀌고 SYN ACK를 보내준다.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;그리고 client에서 SYN을 다시 받게 되면 비로소 ESTABLISHED로 바뀐다.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;이 후 send(), recv()군의 함수들로 계속 통신을 하다가&lt;/li&gt;&lt;br /&gt;&lt;li&gt;client에서 close()호출로 인해 FIN 을 보내고 FIN_WAIT1상태가 되면&lt;/li&gt;&lt;br /&gt;&lt;li&gt;서버에서 이를 받고 ACK를 보낸 후 CLOSE_WAIT으로 상태를 바꾸고&lt;/li&gt;&lt;br /&gt;&lt;li&gt;client에서는 이를 받으면 FIN_WAIT2로 바뀌게 된다.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;client에서 close할 준비가 끝났으므로, 이제는 서버에서 close()가 호출되면 FIN이 전송되고, 상태는 LAST_ACK이 된다.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;client에서는 ACK를 보낸 후 TIME_WAIT상태가 되고, Maximum Segment Lifetime x 2시간 정도 기다리다가 소켓을 닫는다.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;서버에서는 이 ACK를 받고 CLOSED로 상태가 바뀐다.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;close시 일반적으로 client에서 먼저 FIN을 보내고(active close), 서버는 이를 받으면 recv()에 EOF가 전달된다. 서버는 자신이 보낸 FIN에 대한 ACK를 받아야 close된다(passive close).&lt;br/&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;TIME_WAIT이 필요한 이유&lt;/span&gt; client에서 ACK를 보냈는데, 서버가 못받으면, 서버는 LAST_ACK상태에서 일정시간이 지나도 ACK가 안오므로 FIN을 다시 보낸다. 이때 client가 이미 close 한 상태이거나 같은 포트번호로 다른 접속을 시도하고 있다면 처리할 수 없으니까, TIME_WAIT을 두어 다시 들어온 FIN에 대해 ACK를 주는 것이다. (client에서는 그래서 재접속시 다른 포트 번호를 받게 된다).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-475344546487695194?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/475344546487695194/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/06/tcp-status.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/475344546487695194'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/475344546487695194'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/06/tcp-status.html' title='TCP Status'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-9130226268366398852</id><published>2008-06-06T15:17:00.002+09:00</published><updated>2008-06-06T16:20:35.159+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='thread'/><title type='text'>Threads, condition variables</title><content type='html'>Thread를 동기화하는 다른 방법 중의 하나로 Condition variable을 사용하는 것이 있다. condition variable을 잘 사용하면 race-free한 thread 코드를 만들 수 있다. &lt;br/&gt;&lt;br /&gt;condition variable자체는 mutex 에 의해 보호된다. 때문에 condition 상태를 바꾸기 위해서는 먼저 mutex lock을 걸어줘야한다. condition variable(이하 cv) 초기화는 두가지 방법이 있는데, cv가 static이면 PTHREAD_COND_INITIALIZER를 넣어주면 되고 dynamic 이면(동적 할당되었으면) pthread_conf_init()을 쓰면된다. 사용이 끝나면 pthread_cond_destroy()를 호출해준다. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;pthread.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;// 0 for OK&lt;/font&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; pthread_cond_init(pthread_cond_t *&lt;font color="#2e8b57"&gt;&lt;b&gt;restrict&lt;/b&gt;&lt;/font&gt; cond, pthread_condattr_t *&lt;font color="#2e8b57"&gt;&lt;b&gt;restrict&lt;/b&gt;&lt;/font&gt; attr);&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; pthread_cond_destroy(pthread_cond_t *cond);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;cv를 체크하는 방법으로는 아래의 두 함수를 사용할 수 있다. 아래 wait함수를 호출할 때는 인자로 넣어주는 mutex가 lock된 상태여야 한다. 그러면 wait 함수 내부에서 cv를 기다리는 threads list에 함수를 호출한 thread를 넣고 mutex를 unlock한 후 wait상태에 들어가게 된다. wait하다가 condition 이 true가 되면 mutex를 lock한 상태로 리턴하게 된다. timedwait함수의 경우는 얼만큼 오래 기다릴지를 timespec으로 지정해줄 수 있다. timedwait의 경우 condition이 발생하지 않았는데 expire된 경우 lock을 한 상태에서 ETIMEOUT error를 반환한다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;pthread.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;// 0 for OK&lt;/font&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; pthread_cond_wait(pthread_cont_t *&lt;font color="#2e8b57"&gt;&lt;b&gt;restrict&lt;/b&gt;&lt;/font&gt; cond, pthread_mutex_t *&lt;font color="#2e8b57"&gt;&lt;b&gt;restrict&lt;/b&gt;&lt;/font&gt; mutex);&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; pthread_cond_timedwait(pthread_cond_t *&lt;font color="#2e8b57"&gt;&lt;b&gt;restrict&lt;/b&gt;&lt;/font&gt; cond, pthread_mutex_t *&lt;font color="#2e8b57"&gt;&lt;b&gt;restrict&lt;/b&gt;&lt;/font&gt; mutex, &lt;font color="#2e8b57"&gt;&lt;b&gt;const&lt;/b&gt;&lt;/font&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; timespec *&lt;font color="#2e8b57"&gt;&lt;b&gt;restrict&lt;/b&gt;&lt;/font&gt; timeout);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;wait 함수들은 condition이 발생했다는 것은 알려주지만 자신이 이를 처음으로 통보받았다고 보장하지는 않는다. (예를 들어 한개의 condition이 있고 4개의 thread 가 있다면 각각의 thread가 pthread_cond_wait()하다가 condition이 발생해서 pthread_cond_wait()을 빠져 나왔다면, condition이 발생한 것은 확실하지만, 제일 처음 이를 통보받은 thread가 condition과 관련된 부분을 변경했을 수도 있다는 것이다) 때문에 이를 위해  condition을 다시 체크해보아야 한다.&lt;br/&gt;&lt;br /&gt;이번에는 반대로 condition을 변경해주는 부분을 생각해보자. 아래 함수들을 사용해서 두가지 방법으로 condition이 변경되었음을 알려줄 수 있는데, signal 은 기다리고 있는 thread중 하나만 wakeup시켜주고 broadcast는 모든 thread를 깨워준다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;pthread.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;// 0 for OK&lt;/font&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; pthread_cond_sigal(pthread_cond_t *cond);&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; pthread_cond_broadcast(pthread_cond_t *cond);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;아래 APUE 에서의 간단한 예제를 살펴보자.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;pthread.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;// queue의 노드&lt;/font&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; msg {&lt;br /&gt;    &lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; msg *next;&lt;br /&gt;    &lt;font color="#0000ff"&gt;/*&lt;/font&gt;&lt;font color="#0000ff"&gt; ... &lt;/font&gt;&lt;font color="#0000ff"&gt;*/&lt;/font&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; msg *workq;&lt;br /&gt;&lt;font color="#0000ff"&gt;// condition variable&lt;/font&gt;&lt;br /&gt;pthread_cond_t qready = PTHREAD_COND_INITIALIZER;&lt;br /&gt;&lt;font color="#0000ff"&gt;// mutex to protect c.v.&lt;/font&gt;&lt;br /&gt;pthread_mutex_t qlock = PTHREAD_MUTEX_INITIALIZER;&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; process_msg(&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;)&lt;br /&gt;{&lt;br /&gt;    &lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; msg *mp;&lt;br /&gt;    &lt;font color="#a52a2a"&gt;&lt;b&gt;while&lt;/b&gt;&lt;/font&gt; (&lt;font color="#ff00ff"&gt;1&lt;/font&gt;) {&lt;br /&gt;        pthread_mutex_lock(&amp;amp;qlock);&lt;br /&gt;        &lt;font color="#0000ff"&gt;// 이미 lock했어도 아래 ...wait 에서&lt;/font&gt;&lt;br /&gt;        &lt;font color="#0000ff"&gt;// condition variable을 등록 후 내부&lt;/font&gt;&lt;br /&gt;        &lt;font color="#0000ff"&gt;// 적으로 unlock하기 때문에 block상&lt;/font&gt;&lt;br /&gt;        &lt;font color="#0000ff"&gt;// 태가 된다.&lt;/font&gt;&lt;br /&gt;        &lt;font color="#a52a2a"&gt;&lt;b&gt;while&lt;/b&gt;&lt;/font&gt; (workq == &lt;font color="#ff00ff"&gt;NULL&lt;/font&gt;)&lt;br /&gt;            pthread_cond_wait(&amp;amp;qready, &amp;amp;qlock);&lt;br /&gt;        &lt;font color="#0000ff"&gt;// wait 에서 condition 이 바뀐 것을&lt;/font&gt;&lt;br /&gt;        &lt;font color="#0000ff"&gt;// 통보 받고 lock된 상태로 빠져 나왔음&lt;/font&gt;&lt;br /&gt;        &lt;font color="#0000ff"&gt;// 아래 enqueue_msg 에서 broadcast로&lt;/font&gt;&lt;br /&gt;        &lt;font color="#0000ff"&gt;// 통보 했다면 여기서 queue가 비었는지 &lt;/font&gt;&lt;br /&gt;        &lt;font color="#0000ff"&gt;// 다시체크해야하나, 그렇게 할 경우&lt;/font&gt;&lt;br /&gt;        &lt;font color="#0000ff"&gt;// thundering herd가 발생할 소지가 있음&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;        &lt;font color="#0000ff"&gt;// 원래 queue는 tail에서 값을 뽑아야 하는데,&lt;/font&gt;&lt;br /&gt;        &lt;font color="#0000ff"&gt;// 여기서는 head에 넣었다가 head 에서 뽑는다&lt;/font&gt;&lt;br /&gt;        &lt;font color="#0000ff"&gt;// (FIFO가 아니 LIFO,..stack이다..)&lt;/font&gt;&lt;br /&gt;        &lt;font color="#0000ff"&gt;// 이유는... 글쎄 ㅡ.ㅡ;..&lt;/font&gt;&lt;br /&gt;        mp = workq;&lt;br /&gt;        workq = mp-&amp;gt;next;&lt;br /&gt;        pthread_mutex_unlock(&amp;amp;qlock);&lt;br /&gt;        &lt;font color="#0000ff"&gt;// processing msg here&lt;/font&gt;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; enqueue_msg(&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; msg *mp)&lt;br /&gt;{&lt;br /&gt;    pthread_mutex_lock(&amp;amp;qlock);&lt;br /&gt;    mp-&amp;gt;next = workq;&lt;br /&gt;    workq = mp;&lt;br /&gt;    pthread_mutex_unlock(&amp;amp;qlock);&lt;br /&gt;    pthread_cond_signal(&amp;amp;qready);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-9130226268366398852?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/9130226268366398852/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/06/threads-condition-variables.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/9130226268366398852'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/9130226268366398852'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/06/threads-condition-variables.html' title='Threads, condition variables'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-7202260359597585745</id><published>2008-06-06T12:26:00.002+09:00</published><updated>2008-12-12T14:44:44.606+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='thread'/><title type='text'>Thread, manager worker model</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_HMeTW73pU4s/SEizUVssYrI/AAAAAAAAADI/ISiZQ7XpIs8/s1600-h/wm.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://4.bp.blogspot.com/_HMeTW73pU4s/SEizUVssYrI/AAAAAAAAADI/ISiZQ7XpIs8/s320/wm.jpg" alt="" id="BLOGGER_PHOTO_ID_5208610131057337010" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Worker manager model 을 구현할 때 thread를 사용할 수 있다. 외부로 부터 요청된 job들을 관리하기 위해 manager는 일반적으로 queue를 사용한다. job 이 들어오면 어떤  thread가 처리해야할 지 판단한 후에 thread id와 함께 해당 job을 queue에 넣는다. 그럼 각각의 thread들이 queue를 보면서 자신에서 어떤 job이 assign되었는지 확인하고, 꺼내어 작업을 처리할 수 있다.&lt;br /&gt;따라서 worker 나 manager 가 접근할 때 queue 가 lock 되어있어야 하는데, 이럴 때 mutex보다는 읽을 때는 shared mode 로 lock 할 수 있는 rwlock 을 사용한다.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-7202260359597585745?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/7202260359597585745/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/06/thread-manager-worker-model.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/7202260359597585745'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/7202260359597585745'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/06/thread-manager-worker-model.html' title='Thread, manager worker model'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_HMeTW73pU4s/SEizUVssYrI/AAAAAAAAADI/ISiZQ7XpIs8/s72-c/wm.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-6489901778329516239</id><published>2008-06-05T09:40:00.002+09:00</published><updated>2008-06-05T10:01:41.872+09:00</updated><title type='text'>Thread, reader-writer locks</title><content type='html'>mutex는 잠금/해제 두가지 상태밖에 없다. 때문에 한 thread가 읽는 작업을 수행하는 동안 다른 thread들은 읽을 수 없다. reader-writer lock은 잠금의 경우가 read lock/write lock 두 가지 상태가 있기 때문에 여러 thread가 동시에 읽을 수 있다. 사용되는 함수들은 아래와 같다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;pthread.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; pthread_rwlock_init(pthread_rwlock_t *&lt;font color="#2e8b57"&gt;&lt;b&gt;restrict&lt;/b&gt;&lt;/font&gt; rwlock, &lt;font color="#2e8b57"&gt;&lt;b&gt;const&lt;/b&gt;&lt;/font&gt; pthread_rwlockattr_t *&lt;font color="#2e8b57"&gt;&lt;b&gt;restrict&lt;/b&gt;&lt;/font&gt; attr);&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; pthread_rwlock_destroy(pthread_rwlock_t *rwlock);&lt;br /&gt;&lt;font color="#0000ff"&gt;// 0 for OK&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; pthread_rwlock_unlock(pthread_rwlock_t *rwlock);&lt;br /&gt;&lt;font color="#0000ff"&gt;// 0 for OK&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; pthread_rwlock_tryrwlock(pthread_rwlock_t *rwlock);&lt;br /&gt;&lt;font color="#0000ff"&gt;// 0 for OK&lt;/font&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;맨 위의 init/destroy 함수는 mutex를 만들때 사용하는 함수이고, rdlock, wrlock은 각각 읽기/쓰기를 lock하는 함수이다(lock될 때 까지 block되어 기다린다). tryrdlock, tryrwlock들은 non-block으로 동작하는 함수들이다.&lt;br/&gt;&lt;br /&gt;rdlock으로 lock되어 있는 경우, shared mode로 lock된 것이고, wrlock으로 lock한 경우에는 exclusive mode로 lock한 것이다. &lt;br/&gt;&lt;br /&gt;write lock이 된 상황에서 다른 thread들이 rwlock/wrlock 을 하려는 경우 lock이 풀릴 때까지 모두 block되는 반면, read lock이 걸린 경우에는 read lock을 거는 thread들은 바로 접근이 가능하게 되고, write lock을 시도하는 경우에는 걸려있는 모든 read lock들이 해제될 때까지 block 된다.&lt;br /&gt;&lt;br /&gt;비동기 lock 함수들을 사용하는 경우 lock할 수 없는 경우 리턴 값으로 EBUSY에 해당하는 값을 반환한다.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-6489901778329516239?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/6489901778329516239/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/06/thread-reader-writer-locks.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/6489901778329516239'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/6489901778329516239'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/06/thread-reader-writer-locks.html' title='Thread, reader-writer locks'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-7082004165852023915</id><published>2008-06-05T09:10:00.001+09:00</published><updated>2008-06-05T09:21:08.337+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='socket'/><title type='text'>Socket, getsockname</title><content type='html'>이미 binding 된 socket으로 부터 주소정보를 받아올 때 getsockname을 사용한다. 아래와 같이 사용하면 된다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;getsockname(sfd, (&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; sockaddr *)&amp;amp;saddr, &amp;amp;len_saddr);&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-7082004165852023915?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/7082004165852023915/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/06/socket-getsockname.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/7082004165852023915'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/7082004165852023915'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/06/socket-getsockname.html' title='Socket, getsockname'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-8298207860061602818</id><published>2008-06-04T10:03:00.003+09:00</published><updated>2008-06-04T10:09:01.801+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='socket'/><title type='text'>Socket, thundering herd problem</title><content type='html'>network 프로그래밍시 주의해야할 문제 중에 하나로 thundering herd problem이 있다. 천둥이 치면 소떼가 뛴다...는 상황을 비교해서 쓰는 말인데, 여러 thread/process 간에 공유된 자원이 있을 때 자원이 사용가능하게 되지마자 block되어 있던 모든 프로세스들이 깨어나지만 한 프로세스만 자원을 점유하고 나머지는 다시 block되어야 하므로 CPU time을 낭비하게 된다. Mutex 같은 lock을 통해 이런 문제를 해결할 수 있다고 하는데,.. 그런가 ㅡ.ㅡ;,..&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-8298207860061602818?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/8298207860061602818/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/06/socket-thundering-herd-problem.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/8298207860061602818'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/8298207860061602818'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/06/socket-thundering-herd-problem.html' title='Socket, thundering herd problem'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-8725032453509552193</id><published>2008-06-02T11:31:00.004+09:00</published><updated>2008-06-04T10:09:21.351+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='socket'/><title type='text'>Socket, code example</title><content type='html'>간단히 ... 잊지 않을 정도의 코드 예제를 적어본다.&lt;br /&gt;&lt;strong&gt;server side&lt;/strong&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;unistd.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;netinet/in.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;arpa/inet.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;sys/types.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;sys/socket.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; sfd, rsfd;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; sockaddr saddr; &lt;font color="#0000ff"&gt;// listener&lt;/font&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; sockaddr rsaddr;&lt;br /&gt;&lt;br /&gt;sfd = &lt;strong&gt;socket&lt;/strong&gt;(AF_INET, SOCK_STREAM, IPPROTO_IP);&lt;br /&gt;&lt;br /&gt;saddr.sin_family                = AF_INET;&lt;br /&gt;saddr.sin_port          = &lt;font color="#ff00ff"&gt;10000&lt;/font&gt;;&lt;br /&gt;saddr.sin_addr.s_addr   = inet_addr(&lt;font color="#ff00ff"&gt;&amp;quot;100.100.100.100&amp;quot;&lt;/font&gt;);&lt;br /&gt;&lt;font color="#0000ff"&gt;// or inet_aton&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;bind&lt;/strong&gt;(sfd, (&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; sockaddr*)&amp;amp;saddr, &lt;font color="#804040"&gt;&lt;b&gt;sizeof&lt;/b&gt;&lt;/font&gt;(saddr));&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;listen&lt;/strong&gt;(sfd, BACKLOG);&lt;br /&gt;&lt;br /&gt;rsfd = &lt;strong&gt;accept&lt;/strong&gt;(sfd, (&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; sockaddr *)&amp;amp;saddr, &amp;amp;len_rsaddr);&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;recv&lt;/strong&gt;(rsfd, rbuf, &lt;font color="#804040"&gt;&lt;b&gt;sizeof&lt;/b&gt;&lt;/font&gt;(rbuf), &lt;font color="#ff00ff"&gt;0&lt;/font&gt;);&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;send&lt;/strong&gt;(rsfd, sbuf, &lt;font color="#804040"&gt;&lt;b&gt;sizeof&lt;/b&gt;&lt;/font&gt;(sbuf), &lt;font color="#ff00ff"&gt;0&lt;/font&gt;);&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;shutdown&lt;/strong&gt;(rsfd, SHUT_RDWR); &lt;font color="#0000ff"&gt;// or close&lt;/font&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;strong&gt;client side&lt;/strong&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;errno.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;stdio.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;unistd.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;netinet/in.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;arpa/inet.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;sys/socket.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; sfd;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; sockaddr saddr;&lt;br /&gt;&lt;br /&gt;sfd = &lt;strong&gt;socket&lt;/strong&gt;(AF_INET, SOCK_STREAM, IPPROTO_IP);&lt;br /&gt;&lt;br /&gt;saddr.sin_family                = AF_INET;&lt;br /&gt;saddr.sin_port          = &lt;font color="#ff00ff"&gt;10000&lt;/font&gt;;&lt;br /&gt;inet_aton(&lt;font color="#ff00ff"&gt;&amp;quot;100.100.100.100&amp;quot;&lt;/font&gt;, &amp;amp;saddr.sin_addr);&lt;br /&gt;&lt;font color="#0000ff"&gt;// or inet_addr&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;connect&lt;/strong&gt;(sfd, (&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; sockaddr*)saddr, &lt;font color="#804040"&gt;&lt;b&gt;sizeof&lt;/b&gt;&lt;/font&gt;(saddr));&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;send&lt;/strong&gt;(sfd, sbuf, &lt;font color="#804040"&gt;&lt;b&gt;sizeof&lt;/b&gt;&lt;/font&gt;(sbuf), &lt;font color="#ff00ff"&gt;0&lt;/font&gt;);&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;recv&lt;/strong&gt;(sfd, rbuf, &lt;font color="#804040"&gt;&lt;b&gt;sizeof&lt;/b&gt;&lt;/font&gt;(rbuf), &lt;font color="#ff00ff"&gt;0&lt;/font&gt;);&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;close&lt;/strong&gt;(sfd); &lt;font color="#0000ff"&gt;// or shutdown&lt;/font&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-8725032453509552193?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/8725032453509552193/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/06/socket-code-example.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/8725032453509552193'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/8725032453509552193'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/06/socket-code-example.html' title='Socket, code example'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-9060150263094140748</id><published>2008-06-02T08:40:00.005+09:00</published><updated>2008-06-16T23:54:48.040+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='thread'/><title type='text'>Thread, mutex - deadlock/race condition avoidance</title><content type='html'>여러개의 thread가 같은 메모리에 접근할 때 발생할 수 있는 문제가 deadlock, race condition이다. deadlock을 만드는 가장 간단한 방법은 같은 mutex에 두번 lock을 거는 것이다. 혹은 두 thread A,B가 있고 mutex X,Y가 있을 때 A가 X를 lock하고 Y자원을 사용하고자 기다릴때 B가 Y를 lock하고 X자원을 사용하고자하는 경우 이런 상황이 발생한다. thread에서 이런 상황을 피하는 방법으로는 아래의 두가지가 있다.&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;여러 mutex를 사용하는 경우 lock하는 순서를 항상 동일하게 한다. (위의 예라면 항상 X를 lock한 후 Y를 lock하는 식으로 정해서 deadlock을 피할 수 있다)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;자신이 사용하고자 하는 자원이 다른 thread에 의해 사용중인 경우 자신이 점유하고 있는 자원을 해제한 후 기다린다.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;linux에서 사용가능한 mutex관련 함수로는 아래 것들이 있다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;pthread.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; pthread_mutex_lock(pthread_mutex_t *mutex);&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; pthread_mutex_trylock(pthread_mutex_t *mutex);&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; pthread_mutex_unlock(pthread_mutex_t *mutex);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;mutex를 사용하기 위해서는 ..._init(), ..._destroy() 함수들을 사용해야한다. ..._init()함수 사용시 mutex의 종류를 정해줄 수 있는데, 아래와 같은 매크로로 지정할 수 있다.&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;PTHREAD_MUTEX_NORMAL : linux에서는 "timed" mutex이다.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;PTHREAD_MUTEX_RECURSIVE : 여러번 잠글 수 있는 mutex&lt;/li&gt;&lt;br /&gt;&lt;li&gt;PTHREAD_MUTEX_ERRORCHECK : 에러 체크해주는 mutex&lt;/li&gt;&lt;br /&gt;&lt;li&gt;PTHREAD_MUTEX_MUTEX_DEFAULT : linux에서는 첫번째의 ..._NORMAL과 같다.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;위에서 설명한 "timed mutex"는 기본 mutex인데, 중복으로 lock을 걸면 deadlock에 걸리고, 다른 thread가 lock한 상태에서 내가 풀려고 하면 undefined 상태가 된다. errorcheck 타입은 데드락의 경우 에러를 리턴해준다. 그 외에 adaptive mutex가 있는데, 표준은 아니고, 플랫폼에 따라 최적의 매커니즘으로 동작하게 된다. linux에서 SMP가 지원되는 경우 spinlock을 사용하게 되는데, 이때 adaptive mutex를 사용하게 되면 짧은 시간동안의 lock, unlock에 대해 최적의 성능을 지원한다. 대신 비 표준이라 PTHREAD_MUTEX_ADAPTIVE_NP를 통해 초기화 한다.&lt;br/&gt;&lt;br /&gt;이런 mutex 타입을 mutex attribute 함수들을 통해 설정하여 mutex init시 사용하면 된다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;pthread.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; pthread_mutexattr_init(pthread_mutexattr_t *attr);&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; pthread_mutex_gettype(pthread_mutexattr_t *&lt;font color="#2e8b57"&gt;&lt;b&gt;restrict&lt;/b&gt;&lt;/font&gt; attr);&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; pthread_mutex_settype(pthread_mutexattr_t *attr, &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; type);&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; pthread_mutexattr_destroy(pthread_mutexattr_t *attr);&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-9060150263094140748?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/9060150263094140748/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/06/thread-deadlockrace-condition-avoidance.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/9060150263094140748'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/9060150263094140748'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/06/thread-deadlockrace-condition-avoidance.html' title='Thread, mutex - deadlock/race condition avoidance'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-6356196273937060009</id><published>2008-05-29T23:45:00.006+09:00</published><updated>2008-05-29T23:59:27.137+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='thread'/><title type='text'>Thread, basic II</title><content type='html'>thread에 사용되는 함수들은 아래와 같다.&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;pthread_create()&lt;/strong&gt; &lt;br /&gt;thread를 만든다.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;pthread_exit()&lt;/strong&gt; &lt;br /&gt;종료할때 return 대신 쓰면 cleanup함수들이 실행된다.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;pthread_join()&lt;/strong&gt;&lt;br /&gt;다른 thread가 종료될 때까지 현재 코드를 block한다. 종료될 때 그 thread의 리턴값을 받을 수 있다.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;pthread_cancel()&lt;/strong&gt;&lt;br /&gt;다른 thread에게 종료 신호를 보낸다. 종료하는 건 신호를 받은 thread 맘이다. 종료하게 되면 pthread_exit()가 호출된 것처럼 동작한다.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;pthread_cleanup_push()&lt;/strong&gt;&lt;br /&gt;종료시 실행할 함수를 등록한다 like atexit(). 종료시 stack처럼 최근 등록된 순서대로 pop되면서 실행된다.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;pthread_cleanup_pop()&lt;/strong&gt; &lt;br /&gt;위의 ..._push()함수로 등록한 것을 최근 순서로 해제(pop)한다. 단 인자가 0이 아니면 실행하면서 pop한다.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-6356196273937060009?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/6356196273937060009/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/05/thread-basic-ii.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/6356196273937060009'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/6356196273937060009'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/05/thread-basic-ii.html' title='Thread, basic II'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-4039084849256395730</id><published>2008-05-29T09:16:00.003+09:00</published><updated>2008-05-29T09:42:47.496+09:00</updated><title type='text'>Socket, connect()</title><content type='html'>client에서 서버로 접속할 때는 connect()를 사용한다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; connect(&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; sockfd, &lt;font color="#2e8b57"&gt;&lt;b&gt;const&lt;/b&gt;&lt;/font&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; sockaddr *serv_addr, socklen_t addr_len);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;보다시피 사용방법은 아주 간단하다. 먼저 socket을 만들고, 만들 소켓을 접속한 주소가 담긴 sockaddr와 함께 인자로 주면 된다. 입력한 주소가 invalid한 경우에 0을 리턴하기 때문에 아래와 같이 코드를 만들게 된다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;netinet/in.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;arpa/inet.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;sys/socket.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;     sock_fd;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;     saddr;&lt;br /&gt;&lt;br /&gt;sfd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);&lt;br /&gt;&lt;br /&gt;saddr.sin_family        = AF_INET;&lt;br /&gt;saddr.sin_port          = &lt;font color="#ff00ff"&gt;80&lt;/font&gt;; &lt;font color="#0000ff"&gt;// port&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#804040"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt; (inet_aton(&lt;font color="#ff00ff"&gt;&amp;quot;100.100.100.100&amp;quot;&lt;/font&gt;), &amp;amp;(saddr.sin_addr) == &lt;font color="#ff00ff"&gt;0&lt;/font&gt;)&lt;br /&gt;        fprintf(&lt;font color="#ff00ff"&gt;stderr&lt;/font&gt;, &lt;font color="#ff00ff"&gt;&amp;quot;error : inet_aton&lt;/font&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;);&lt;br /&gt;&lt;font color="#804040"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt; (connect(sfd, (&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; sockaddr *)&amp;amp;saddr, &lt;font color="#804040"&gt;&lt;b&gt;sizeof&lt;/b&gt;&lt;/font&gt;(saddr)) == -&lt;font color="#ff00ff"&gt;1&lt;/font&gt;)&lt;br /&gt;        perror(&lt;font color="#ff00ff"&gt;&amp;quot;connect&amp;quot;&lt;/font&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-4039084849256395730?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/4039084849256395730/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/05/socket-connect.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/4039084849256395730'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/4039084849256395730'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/05/socket-connect.html' title='Socket, connect()'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-6681236484777113544</id><published>2008-05-27T09:49:00.006+09:00</published><updated>2008-05-29T23:20:19.625+09:00</updated><title type='text'>Socket, bind(), listen() and accept()</title><content type='html'>socket()을 통해 소켓을 생성했다면 다음은 bind()이다. bind()는 아래와 같다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;sys/types.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;sys/socket.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; bind(&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; sockfd, &lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; sockaddr *my_addr, socklen_t addrlen);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;sockfd는 앞서 만든 socket이고, sockaddr은 IP/Port 등의 주소 정보를 가진 구조체다. addrlen은 이 구조체의 크기이다. Unix socket을 사용하는 경우 sockaddr_un을 사용하지만, Network socket을 사용하는 경우 sockaddr_in을 사용한다. 두 구조체 모두 bind에 넣을 때는 (sockaddr *)로 캐스팅해서 넣어준다(bind내부에서 sockaddr로 캐스팅된 구조체의 앞부분을 보고 network socket인지 unix socket인지 알수 있다). 구조체를 잠깐 살펴 보자.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; sockaddr_in {&lt;br /&gt;    &lt;font color="#2e8b57"&gt;&lt;b&gt;unsigned&lt;/b&gt;&lt;/font&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;short&lt;/b&gt;&lt;/font&gt; sin_family;  &lt;font color="#0000ff"&gt;// AF_INET&lt;/font&gt;&lt;br /&gt;    &lt;font color="#2e8b57"&gt;&lt;b&gt;unsigned&lt;/b&gt;&lt;/font&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;short&lt;/b&gt;&lt;/font&gt; sin_port;&lt;br /&gt;    &lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; in_addr sin_addr;&lt;br /&gt;    &lt;font color="#2e8b57"&gt;&lt;b&gt;char&lt;/b&gt;&lt;/font&gt; sin_zero[&lt;font color="#ff00ff"&gt;8&lt;/font&gt;];           &lt;font color="#0000ff"&gt;// not used&lt;/font&gt;&lt;br /&gt;}&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; sockaddr_un {&lt;br /&gt;    &lt;font color="#2e8b57"&gt;&lt;b&gt;short&lt;/b&gt;&lt;/font&gt;   sun_family;&lt;br /&gt;    &lt;font color="#2e8b57"&gt;&lt;b&gt;char&lt;/b&gt;&lt;/font&gt;    sun_path[&lt;font color="#ff00ff"&gt;108&lt;/font&gt;];&lt;br /&gt;}&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; in_addr {&lt;br /&gt;    &lt;font color="#2e8b57"&gt;&lt;b&gt;unsigned&lt;/b&gt;&lt;/font&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;long&lt;/b&gt;&lt;/font&gt; s_addr;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;특별한 건 없고, AF_INET/AF_UNIX, 주소, 포트 번호 등이 들어가 있다. 주소는 in_addr 구조체로 들어가 있는데, unsigned long 타입으로 되어 있다. IP주소가 x.x.x.x 식으로 되어 있고 x &lt; 256 이므로(8비트), 32bit 만 있으면 충분하다. 그래서 in_addr의 s_addr이 unsinged long (32bit) 이다. 여기에 INADDR_ANY (0)을 넣으면 서버에 지정된 모든 IP에 해당된다. 여기에 주소를 넣을 때는 inet_addr(), inet_aton()을 사용할 수 있는데, 전자의 경우에는 unix 표준이지만, 리턴되는 -1값이 INADDR_NONE(255.255.255.255) 인 경우와 에러인 경우를 모두 포함하므로 구별하기가 모호하다. inet_aton은 구분이 가능하지만 표준에 들어있지 않아.. 거시기 하다ㅡㅡ; 암튼 대충 이렇고, 실제로 주소를 넣는 코드는 아래와 같다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; sockaddr_in saddr_svr;&lt;br /&gt;saddr_svr.sin_family    = AF_INET;&lt;br /&gt;saddr_svr.sin_port      = htons(&lt;font color="#ff00ff"&gt;12000&lt;/font&gt;); &lt;font color="#0000ff"&gt;//port number&lt;/font&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;// 방법1&lt;/font&gt;&lt;br /&gt;saddr_svr.sin_addr.s_addr =&lt;br /&gt;                inet_addr (&lt;font color="#ff00ff"&gt;&amp;quot;192.168.100.20&amp;quot;&lt;/font&gt;);&lt;br /&gt;&lt;font color="#0000ff"&gt;// 방법2&lt;/font&gt;&lt;br /&gt;&lt;font color="#804040"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt; (!inet_aton(&lt;font color="#ff00ff"&gt;&amp;quot;192.168.100.20&amp;quot;&lt;/font&gt;, &amp;amp;(saddr_svr.sin_addr.s_addr)))&lt;br /&gt;{&lt;br /&gt;    fprintf (&lt;font color="#ff00ff"&gt;stderr&lt;/font&gt;, &lt;font color="#ff00ff"&gt;&amp;quot;inet_aton&amp;quot;&lt;/font&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;bind는 성공시 0을, 실패시 -1을 리턴하고 errno를 설정해준다. 위처럼 설정한 sockaddr_in을 아래처럼 binding하면된다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#804040"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt; (bind(sock_fd, (sockaddr *)saddr_svr, &lt;font color="#804040"&gt;&lt;b&gt;sizeof&lt;/b&gt;&lt;/font&gt;(saddr_svr)) == -&lt;font color="#ff00ff"&gt;1&lt;/font&gt;)&lt;br /&gt;    perror(&lt;font color="#ff00ff"&gt;&amp;quot;bind&amp;quot;&lt;/font&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;bind된 socket으로 실제 TCP 요청을 받기 위해(TCP 접속을 위해) listen()을 사용한다. 인자로 backlog 값이 사용되는데, 커널에서 큐로 구현되어 있으며 default로 1024 로 되어 1024개 까지 TCP 접속을 허용할 수 있게된다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; listen (&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; s, &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; backlog);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;생성된 소켓으로 외부 요청을 받을 수 있도록 주소를 binding하고 listen 하기 시작했다면, 요청을 기다리다가 들어온 요청을 accept() 하여 받을 수 있다. accept 함수는 bind 소켓과 client의 주소정보를 담을 sockaddr 구조체를 인자로 주면 요청이 들어올 때까지 코드를 block 한다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; client_sockfd;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; sockaddr_in client_saddr;&lt;br /&gt;socklen_t client_socklen;&lt;br /&gt;&lt;br /&gt;client_socklen = &lt;font color="#804040"&gt;&lt;b&gt;sizeof&lt;/b&gt;&lt;/font&gt;(client_saddr);&lt;br /&gt;client_sockfd = accept(sock_fd, (&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; sockaddr *)&amp;amp;client_saddr, &amp;amp;client_socklen);&lt;br /&gt;&lt;br /&gt;printf(&lt;font color="#ff00ff"&gt;&amp;quot;client : &lt;/font&gt;&lt;font color="#6a5acd"&gt;%s&lt;/font&gt;&lt;font color="#ff00ff"&gt;:&lt;/font&gt;&lt;font color="#6a5acd"&gt;%d&lt;/font&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;, inet_ntoa(client_saddr.sin_addr), ntohs(client_saddr.sin_port));&lt;br /&gt;&lt;br /&gt;close(...);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;위 코드의 실행시 client의 요청에 대해 아래와 같이 출력된다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;./server 127.0.0.1 21650&lt;br /&gt;&lt;b&gt;Client&lt;/b&gt; : fd(4) 127.0.0.1:35130&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-6681236484777113544?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/6681236484777113544/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/05/socket-bind.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/6681236484777113544'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/6681236484777113544'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/05/socket-bind.html' title='Socket, bind(), listen() and accept()'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-6836698426529831802</id><published>2008-05-23T23:30:00.002+09:00</published><updated>2008-12-12T14:44:44.879+09:00</updated><title type='text'>Pointer's pointer - 포인터의 포인터</title><content type='html'>함수 인자에 포인터의 포인터를 사용하는 경우가 있으나, 가끔씩이라 햇갈릴 때가 있다. 어떤 경우에 사용하게 되는지와 그 이유를 정리해보자.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_HMeTW73pU4s/SDbeSly3vcI/AAAAAAAAADA/YBvvtyxxH34/s1600-h/1346799856.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_HMeTW73pU4s/SDbeSly3vcI/AAAAAAAAADA/YBvvtyxxH34/s320/1346799856.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5203590830437678530" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;그림처럼 int a와 int *pa 가 있다고 치자. pa = a로 pa가 a를 가리키는 상황이면 pa는 a의 주소인 0x1001을 가지고 있다. 그래서 pa = 0x1001, *pa = 3 이다. 정수 포인터(int *)를 인자로 받는 함수 fa에서는 a값에 대해서만 참조가 가능하다. 그런데, 포인터가 가리키는 값을 바꾸고 싶은 경우가 있다. (스택이나 리스트 같은 자료구조를 구현하다 보면 필요하게 된다. 스택 포인터를 인자로 받는 push(node *stack, void* data) 같은 경우를 생각해보자. 새로운 공간을 할당하여 data를 넣은 후 이를 stack의 top node로 하고 node-&gt;next = stack로 바꿔줘야한다. 그러나 node *만을 받아서는 이를 변경하는 것이 불가능하다.) 그래서 사용하는 것이 포인터의 포인터이다. fb와 같이 포인터의 포인터를 인자로 받는 함수를 생각해보자. 함수 fb (int **ppa) 에 대해서 fb(&amp;pa) 와 같이 인자를 주었다면, 함수에는 pa의 주소인 0x2001이 들어간다. 그래서 함수 fb 안에서는 ppa = 0x2001, *ppa = 0x1001, **ppa = 3 으로 포인터의 주소, 포인터가 가리키는 값의 주소, 포인터가 가리키는 값 세가지를 모두 접근할 수 있으며, 포인터가 다른 데이터를 가리키도록 바꿀 수도 있게 된다(스택에서는 그래서 push(node **stack, void* data) 와 같은 식이 되어야 한다). 이를 위해 포인터의 포인터가 사용된다.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-6836698426529831802?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/6836698426529831802/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/05/pointers-pointer.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/6836698426529831802'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/6836698426529831802'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/05/pointers-pointer.html' title='Pointer&apos;s pointer - 포인터의 포인터'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_HMeTW73pU4s/SDbeSly3vcI/AAAAAAAAADA/YBvvtyxxH34/s72-c/1346799856.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-2635133951572615091</id><published>2008-05-23T09:30:00.007+09:00</published><updated>2008-12-12T14:44:45.105+09:00</updated><title type='text'>Socket, TCP flow of both sides</title><content type='html'>TCP 소켓 통신은 서버와 클라이언트에 따라 아래와 같은 순서로 함수 호출이 일어난다.&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Server&lt;br/&gt;&lt;br /&gt;socket() - bind() - listen() - accept() - recv(), send() - close()(passive)&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Client&lt;/li&gt;&lt;br /&gt;socket() - bin() - connect() - recv(),send() - close()(active)&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;웹상에 이쁜그림이 없어 간단히 그려보았다. (client에서는 connect()가 bind()를 포함 하므로 생략해도 된다)&lt;br/&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_HMeTW73pU4s/SDYWrly3vbI/AAAAAAAAAC4/wvC5z9ducDk/s1600-h/tcpflow.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_HMeTW73pU4s/SDYWrly3vbI/AAAAAAAAAC4/wvC5z9ducDk/s400/tcpflow.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5203371357608852914" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-2635133951572615091?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/2635133951572615091/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/05/socket-tcp-flow-of-both-sides.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/2635133951572615091'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/2635133951572615091'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/05/socket-tcp-flow-of-both-sides.html' title='Socket, TCP flow of both sides'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_HMeTW73pU4s/SDYWrly3vbI/AAAAAAAAAC4/wvC5z9ducDk/s72-c/tcpflow.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-7061195287886494315</id><published>2008-05-23T08:41:00.002+09:00</published><updated>2008-05-23T09:01:41.450+09:00</updated><title type='text'>Signals, sending signal with payload</title><content type='html'>프로세스에 signal을 보낼 때 payload 를 줄 수 있다. kill(), raise()가 아닌 sigqueue()를 사용하는데, 아래와 같다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;signal.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;union&lt;/b&gt;&lt;/font&gt; sigval {&lt;br /&gt;        &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; sigval_int;&lt;br /&gt;        &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; *sigval_ptr;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; sigqueue (pid_t pid, &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; signo, &lt;font color="#2e8b57"&gt;&lt;b&gt;const&lt;/b&gt;&lt;/font&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;union&lt;/b&gt;&lt;/font&gt; sigval value);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;그래서 아래와 같이 간단히 payload를 줄 수 있다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;sigval  value;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;     ret;&lt;br /&gt;&lt;br /&gt;value.sigval_int = &lt;font color="#ff00ff"&gt;404&lt;/font&gt;;&lt;br /&gt;&lt;br /&gt;ret = sigqueue(&lt;font color="#ff00ff"&gt;4500&lt;/font&gt;, &lt;font color="#ff00ff"&gt;SIGUSR1&lt;/font&gt;, value);&lt;br /&gt;&lt;font color="#804040"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt; (ret)&lt;br /&gt;        perror(&lt;font color="#ff00ff"&gt;&amp;quot;sigqueue&amp;quot;&lt;/font&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-7061195287886494315?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/7061195287886494315/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/05/signals-sending-signal-with-payload.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/7061195287886494315'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/7061195287886494315'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/05/signals-sending-signal-with-payload.html' title='Signals, sending signal with payload'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-3870958480251636883</id><published>2008-05-22T14:17:00.004+09:00</published><updated>2008-05-23T09:26:29.251+09:00</updated><title type='text'>Socket, byte order</title><content type='html'>사용하는 시스템의 architecture가 big-endian인지 little-endian인지를 알아야 보낼 데이터를 socket에서 사용하는 endian에 맞게 고쳐 보낼 수 있다. system의 endian을 알기 위한 테스트는 아래처럼 할 수 있다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;union&lt;/b&gt;&lt;/font&gt; btye_long {&lt;br /&gt;        &lt;font color="#2e8b57"&gt;&lt;b&gt;long&lt;/b&gt;&lt;/font&gt; l;&lt;br /&gt;        &lt;font color="#2e8b57"&gt;&lt;b&gt;unsigned&lt;/b&gt;&lt;/font&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;char&lt;/b&gt;&lt;/font&gt; c[&lt;font color="#ff00ff"&gt;4&lt;/font&gt;];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; main()&lt;br /&gt;{&lt;br /&gt;        &lt;font color="#2e8b57"&gt;&lt;b&gt;union&lt;/b&gt;&lt;/font&gt; byte_long         bl;&lt;br /&gt;        bl.l                    = &lt;font color="#ff00ff"&gt;1200000L&lt;/font&gt;;&lt;br /&gt;        printf (&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;&lt;font color="#6a5acd"&gt;%02x&lt;/font&gt;&lt;font color="#ff00ff"&gt;-&lt;/font&gt;&lt;font color="#6a5acd"&gt;%02x&lt;/font&gt;&lt;font color="#ff00ff"&gt;-&lt;/font&gt;&lt;font color="#6a5acd"&gt;%02x&lt;/font&gt;&lt;font color="#ff00ff"&gt;-&lt;/font&gt;&lt;font color="#6a5acd"&gt;%02x&lt;/font&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;, bl.c[&lt;font color="#ff00ff"&gt;0&lt;/font&gt;], bl.c[&lt;font color="#ff00ff"&gt;1&lt;/font&gt;], bl.c[&lt;font color="#ff00ff"&gt;2&lt;/font&gt;], bl.c[&lt;font color="#ff00ff"&gt;3&lt;/font&gt;]);&lt;br /&gt;        bl.l = htonl(bl.l);&lt;br /&gt;        printf (&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;&lt;font color="#6a5acd"&gt;%02x&lt;/font&gt;&lt;font color="#ff00ff"&gt;-&lt;/font&gt;&lt;font color="#6a5acd"&gt;%02x&lt;/font&gt;&lt;font color="#ff00ff"&gt;-&lt;/font&gt;&lt;font color="#6a5acd"&gt;%02x&lt;/font&gt;&lt;font color="#ff00ff"&gt;-&lt;/font&gt;&lt;font color="#6a5acd"&gt;%02x&lt;/font&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;, bl.c[&lt;font color="#ff00ff"&gt;0&lt;/font&gt;], bl.c[&lt;font color="#ff00ff"&gt;1&lt;/font&gt;], bl.c[&lt;font color="#ff00ff"&gt;2&lt;/font&gt;], bl.c[&lt;font color="#ff00ff"&gt;3&lt;/font&gt;]);&lt;br /&gt;        &lt;font color="#804040"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt; &lt;font color="#ff00ff"&gt;0&lt;/font&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;font color="#0000ff"&gt;// from ALSP&lt;/font&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;근데, 이건 좀 복잡하고, 사실 if (120000L == htonl(120000L)) 만 해도 알 수 있다 ㅡ.ㅡ; 인텔 계열은 little endian 인데 반해 network packet에서는 bigendian을 사용한다. 그래서 항상 byte order를 변경해주어여 하는데 이때 사용하는 함수군이 아래와 같다.&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;htons&lt;/strong&gt; host endian to network endian converting of 2bytes short&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;htonl&lt;/strong&gt; host endian to network endian converting of 4bytes long&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;ntohs&lt;/strong&gt; network endian to host endian converting of 2bytes short&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;ntohl&lt;/strong&gt; network endian to host endian converting of 2bytes long&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;double, float 등의 변환은 ... 일단 생략 --;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-3870958480251636883?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/3870958480251636883/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/05/socket-byte-order.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/3870958480251636883'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/3870958480251636883'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/05/socket-byte-order.html' title='Socket, byte order'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-4608776487513631981</id><published>2008-05-22T09:33:00.003+09:00</published><updated>2008-05-22T14:12:37.741+09:00</updated><title type='text'>Signals, advanced management</title><content type='html'>signal()을 통한 signal 처리는 기본적인 것이다. 조금 진보된 형태의 signal 처리로 sigaction()이 있다. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;signal.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; sigaction (&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; signo, &lt;font color="#2e8b57"&gt;&lt;b&gt;const&lt;/b&gt;&lt;/font&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; sigaction *act, &lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; sigaction *oldact);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;sigaction()은 핸들러가 돌아가는 동안에 특정 signal을 block할 수도 있고, 핸들러가 프로세스의 상태에 대한 여러 정보들을 제공받을 수도 있다. 위에서는 signo에 해당하는 signal에 대한 핸들을 act로 바꿔주며, 이전의 핸들(behavior)을 oldact에 담아준다. 핸들을 등록할 떄 사용하는 sigaction struct에 대해 간단히 알아보자.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; sigaction {&lt;br /&gt;    &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; (*sa_handler)(&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;);&lt;br /&gt;    &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; (*sa_sigaction)(&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;, siginfo_t, &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; *);&lt;br /&gt;    sigset_t sa_mask;&lt;br /&gt;    &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; sa_flags;&lt;br /&gt;    &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; (*sa_restorer)(&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;); &lt;font color="#0000ff"&gt;/*&lt;/font&gt;&lt;font color="#0000ff"&gt; OBSOLETE &lt;/font&gt;&lt;font color="#0000ff"&gt;*/&lt;/font&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;이 구조체에서는 두가지 형태의 핸들러를 등록할 수 있다. sa_handler는 signal()에서 등록하던 핸들러와 같은 형태이고, sa_sigaction은 sa_flags에 SA_SIGINFO 가 켜져있는 경우 사용하는 핸들러인데 아래와 같은 형식을 취한다. 이 flag에 따라 둘 중 하나의 핸들러를 사용하기 때문에 어떤 시스템의 경우에는 이 부분을 union으로 정의하기도 하므로 두개의 핸들러를 모두 등록하는 일은 되도록 피하자. sa_flags에 SA_NODEFER가 켜져있지 않는 한 처리하고 있는 signal과 동일한 signal은 block되며 다른 signal의 block은 sa_mask를 통해 추가할 수 있다(물론 SIGKILL, SIGSTOP은 block안된다).&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; handler(&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; signo, siginfo_t *si, &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; *ucontext);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;인자로 signal 번호뿐 아니라 siginfo_t도 받고, void *인 ucontext도 받는다. 다시 sigaction 구조체로 돌아가서 sa_flag 얘기를 더하면, 아래와 같은 flag들을 사용할 수 있다.&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;SA_NOCLDSTOP&lt;/strong&gt; child가 stop, resume되어도 noti안한다.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;SA_NOCLDWAIT&lt;/strong&gt; child 에 대해 wait() 안하겠다...&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;SA_ONSTACK&lt;/strong&gt; signal이 왔을 때 alternative signal stack을 쓰겠다는 것인데... 잘모르겠다.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;SA_RESETHAND&lt;/strong&gt; 'one-shot' 모드이다. 현재 핸들러를 이번 한번만 쓰고 다음에는 default 핸들러를 쓰겠다는...&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;SA_RESTART&lt;/strong&gt; signal에 의해 인터럽된 system call을 BSD style로 restart하겠다는 건데..ㅡ.ㅡ;.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;SA_SIGINFO 일때 사용하는 핸들러에 전달해 주는 siginfo_t 구조체에 어떤 정보들이 있는지 살펴보자&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;typedef&lt;/b&gt;&lt;/font&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; siginfo_t {&lt;br /&gt;    &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; si_signo;&lt;br /&gt;    &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; si_errno;&lt;br /&gt;    &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; si_code;&lt;br /&gt;    pid_t si_pid;&lt;br /&gt;    uid_t si_uid;   &lt;font color="#0000ff"&gt;/*&lt;/font&gt;&lt;font color="#0000ff"&gt; process real UID &lt;/font&gt;&lt;font color="#0000ff"&gt;*/&lt;/font&gt;&lt;br /&gt;    &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; si_status;&lt;br /&gt;    &lt;font color="#2e8b57"&gt;&lt;b&gt;clock_t&lt;/b&gt;&lt;/font&gt; si_utime;&lt;br /&gt;    &lt;font color="#2e8b57"&gt;&lt;b&gt;clock_t&lt;/b&gt;&lt;/font&gt; si_stime;&lt;br /&gt;    sigval_t si_value; &lt;font color="#0000ff"&gt;/*&lt;/font&gt;&lt;font color="#0000ff"&gt; payload &lt;/font&gt;&lt;font color="#0000ff"&gt;*/&lt;/font&gt;&lt;br /&gt;    &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; si_int;     &lt;font color="#0000ff"&gt;/*&lt;/font&gt;&lt;font color="#0000ff"&gt; POSIX.1b signal &lt;/font&gt;&lt;font color="#0000ff"&gt;*/&lt;/font&gt;&lt;br /&gt;    &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; *si_ptr;   &lt;font color="#0000ff"&gt;/*&lt;/font&gt;&lt;font color="#0000ff"&gt; POSIX.1b signal &lt;/font&gt;&lt;font color="#0000ff"&gt;*/&lt;/font&gt;&lt;br /&gt;    &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; *si_addr;  &lt;font color="#0000ff"&gt;/*&lt;/font&gt;&lt;font color="#0000ff"&gt; dault시 memory location &lt;/font&gt;&lt;font color="#0000ff"&gt;*/&lt;/font&gt;&lt;br /&gt;    &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; si_band;&lt;br /&gt;    &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; si_fd;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;si_signo&lt;/strong&gt;받은 signal number&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;si_errno&lt;/strong&gt;이 signal과 관련된 error code&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;si_pid&lt;/strong&gt;종료된 프로세스의 pid(SIGCHLD signal인 경우 사용)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;si_uid&lt;/strong&gt;(SIGCHLD signal인 경우 사용)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;si_status&lt;/strong&gt;exit status (SIGCHLD signal인 경우 사용)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;si_utime&lt;/strong&gt;종료된 프로세스가 소비한 user time(SIGCHLD signal인 경우 사용)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;si_stime&lt;/strong&gt;종료된 프로세스가 소비한 system time(SIGCHLD signal인 경우 사용)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;si_value&lt;/strong&gt;union of si_int, si_ptr&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;si_int&lt;/strong&gt;payload type이 int인 상태에서 sigqueue()에 보내진 signals&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;si_ptr&lt;/strong&gt;payload type이 void *인 상태에서 sigqueue()에 보내진 signals&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;si_addr&lt;/strong&gt;SIGBUS,SIGFPE,SIGILL,SIGESV 등인 경우 fault가 일어난 address를 가지고 있음&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;si_band&lt;/strong&gt; OOB 인 경우 fd의 oob, priority info를 가지고 있음&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;si_fd&lt;/strong&gt; SIGPOLL 일때 작업이 완료된 파일의 fd를 가지고 있음&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;siginfo_t의 다른 원소인 si_code는 signal을 누가 발생 시켰는지, 왜 발생했는지에 대한 정보를 알려주는데, 몇개만 살펴보면 아래와 같다.&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;SI_ASYNCIO&lt;/strong&gt;asynchronous I/O 끝나서 발생&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;SI_KERNEL&lt;/strong&gt;커널이 보냈음&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;SI_TIMER&lt;/strong&gt;POSIX timer expired&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;SI_USER&lt;/strong&gt;사용자가 kill(), raise()로 보냈음&lt;/li&gt;&lt;br /&gt;&lt;li&gt;SIGCHLD 인경우에는 아래의 si_code 들이 넘어온다.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;CLD_CONTINUED&lt;/strong&gt; child stopped but resumed.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;CLD_DUMPED&lt;/strong&gt; child terminated abnormally.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;CLD_EXITED&lt;/strong&gt; child terminated via exit().&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;CLD_KILLED&lt;/strong&gt; child was killed.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;CLD_STOPPED&lt;/strong&gt; child stopped.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;CLD_TRAPPED&lt;/strong&gt; child hit a trap.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;POLL_ERR&lt;/strong&gt; I/O error&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;POLL_HUP&lt;/strong&gt; device hung up or disconnect&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;POLL_IN&lt;/strong&gt; available to read&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;POLL_MSG&lt;/strong&gt; message is available&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;POLL_OUT&lt;/strong&gt; available to write&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;POLL_PRI&lt;/strong&gt; available high-priority data to read&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;그외에 SIGFPE, SIGBUS, SIGILL 등의 경우는 넘어가자.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-4608776487513631981?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/4608776487513631981/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/05/signals-advanced-management.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/4608776487513631981'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/4608776487513631981'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/05/signals-advanced-management.html' title='Signals, advanced management'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-5971425763309423246</id><published>2008-05-21T09:52:00.004+09:00</published><updated>2008-05-22T14:17:50.180+09:00</updated><title type='text'>Socket, create</title><content type='html'>기왕 공부하는거 socket도 복습해보자.&lt;br/&gt;&lt;br /&gt;소켓은 도메인에 따라 &lt;strong&gt;unix socket&lt;/strong&gt;, &lt;strong&gt;network socket&lt;/strong&gt; 으로 구분하는데 앞의 것은 한 host 내에서 사용할 때이고 뒤의 것은 여러 호스트에 걸친경우 이다.&lt;br/&gt;&lt;br /&gt;소켓은 타입에 따라 &lt;strong&gt;datagram&lt;/strong&gt; 이냐, &lt;strong&gt;stream&lt;/strong&gt;이냐의 차이를 가지는데 데이터를 일정한 단위로 나누어 보내냐 혹 stream 형태로 연결을 유지하면서 보내냐의 차이다(거의 UDP, TCP의 차이).&lt;br/&gt;&lt;br /&gt;소켓은 아래처럼 간단하게 만들어진다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;sys/socket.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; socket(&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; domain, &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; type, &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; protocol);&lt;br /&gt;&lt;font color="#0000ff"&gt;// domain   AF_UNIX (unix socket), &lt;/font&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;//          AF_INET(network socket) (AF = PF)&lt;/font&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;// type     SOCK_STREAM&lt;/font&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;//          SOCK_DGRAM&lt;/font&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;//          SOCK_RAW&lt;/font&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;// protocol IPPROTO_IP (0) (for both)&lt;/font&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;//          IPPROTO_TCP (for SOCK_STREAM)&lt;/font&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;//          IPPROTO_UDP (for SOCK_DGRAM)&lt;/font&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;//          IPPROTO_ICMP&lt;/font&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;// ex.&lt;/font&gt;&lt;br /&gt;&lt;font color="#804040"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt; ((sd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) == -&lt;font color="#ff00ff"&gt;1&lt;/font&gt;)&lt;br /&gt;        fprintf(&lt;font color="#ff00ff"&gt;stderr&lt;/font&gt;, &lt;font color="#ff00ff"&gt;&amp;quot;error socket&lt;/font&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;);&lt;br /&gt;&lt;font color="#804040"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt; ((sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP)) == -&lt;font color="#ff00ff"&gt;1&lt;/font&gt;)&lt;br /&gt;        fprintf(&lt;font color="#ff00ff"&gt;stderr&lt;/font&gt;, &lt;font color="#ff00ff"&gt;&amp;quot;error socket&lt;/font&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;);&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;SOCK_DGRAM(UDP)이나 SOCK_STREAM(TCP)이나 IP 아래에서 동작하므로, 위처럼 IPPRORO_IP를 가지고 생성할 수 있다.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-5971425763309423246?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/5971425763309423246/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/05/socket-create.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/5971425763309423246'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/5971425763309423246'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/05/socket-create.html' title='Socket, create'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-2155819465360558048</id><published>2008-05-21T08:52:00.003+09:00</published><updated>2008-05-21T09:35:03.576+09:00</updated><title type='text'>Signals, signal block with masking</title><content type='html'>프로세스는 여러개의 signal을 block 시킬 수 있는데,이 때 sigprocmask()를 사용한다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;signal.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; sigprocmask (&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; how, &lt;font color="#2e8b57"&gt;&lt;b&gt;const&lt;/b&gt;&lt;/font&gt; sigset_t *set,&lt;br /&gt;                sigset_t *oldset);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;how에 SIG_BLOCK 를 주면 sigset에 해당하는 signal들이 block되고, SIG_UNBLOCK을 주면 해제된다. SIG_SETMASK는 ... 잘 모르겠다 ㅡㅡ; set이 NULL 인 경우에는 현재 block 되어 있는 signal들이 oldset에 찍혀 나온다. &lt;br/&gt;&lt;br /&gt;이런식으로 block한 signal들은 unblock하면 프로세스에 전달되는데, pending된 signal들은 sigpending(sigset_t *set)을 통해 확인할 수 있다. 일반적으로 signal을 고려한 critical section의 처리는 아래와 같은 순서로 진행된다.&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;sigprocmask()로 특정 signal들을 block한다.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;critical section 을 처리한다.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;sigsuspend()로 block한 signal 들이 처리될 때 까지 기다린다.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;이러한 식으로 signal set을 통해 간단한 코드를 짜보면,&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;signal.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;stdio.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; sig_handler(&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; signo)&lt;br /&gt;{&lt;br /&gt;    fprintf(&lt;font color="#ff00ff"&gt;stderr&lt;/font&gt;, &lt;font color="#ff00ff"&gt;&amp;quot;signal caught : &lt;/font&gt;&lt;font color="#6a5acd"&gt;%s&lt;/font&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;, sys_siglist[signo]);&lt;br /&gt;    &lt;font color="#804040"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; main()&lt;br /&gt;{&lt;br /&gt;    sigset_t    sigset;&lt;br /&gt;    sigset_t    sigset_old;&lt;br /&gt;    sigset_t    sigset_test;&lt;br /&gt;&lt;br /&gt;    &lt;font color="#804040"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt; (signal(&lt;font color="#ff00ff"&gt;SIGINT&lt;/font&gt;, sig_handler) == &lt;font color="#ff00ff"&gt;SIG_ERR&lt;/font&gt;) {&lt;br /&gt;        fprintf(&lt;font color="#ff00ff"&gt;stderr&lt;/font&gt;, &lt;font color="#ff00ff"&gt;&amp;quot;SIGINT handle can't be registered&lt;/font&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;);&lt;br /&gt;    }&lt;br /&gt;    &lt;font color="#804040"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt; (signal(&lt;font color="#ff00ff"&gt;SIGQUIT&lt;/font&gt;, sig_handler) == &lt;font color="#ff00ff"&gt;SIG_ERR&lt;/font&gt;) {&lt;br /&gt;        fprintf(&lt;font color="#ff00ff"&gt;stderr&lt;/font&gt;, &lt;font color="#ff00ff"&gt;&amp;quot;SIGINT handle can't be registered&lt;/font&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    sigemptyset(&amp;amp;sigset);&lt;br /&gt;    sigaddset(&amp;amp;sigset, &lt;font color="#ff00ff"&gt;SIGQUIT&lt;/font&gt;);&lt;br /&gt;    sigprocmask(SIG_BLOCK, &amp;amp;sigset, &amp;amp;sigset_old);&lt;br /&gt;    pause();&lt;br /&gt;    sigpending(&amp;amp;sigset_test);&lt;br /&gt;    &lt;font color="#804040"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt; (sigismember(&amp;amp;sigset_test, &lt;font color="#ff00ff"&gt;SIGQUIT&lt;/font&gt;))&lt;br /&gt;        printf(&lt;font color="#ff00ff"&gt;&amp;quot;SIGQUIT is pending&lt;/font&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;);&lt;br /&gt;    sigsuspend(&amp;amp;sigset_old);&lt;br /&gt;    &lt;font color="#0000ff"&gt;//sigprocmask(SIG_UNBLOCK, &amp;amp;sigset, NULL);&lt;/font&gt;&lt;br /&gt;    &lt;font color="#804040"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;SIGINT, SIGQUIT 핸들러를 등록하고, sigset에 SIGQUIT을 넣고 sigprocmask로 블럭한다음 pause()로 signal을 기다린다(SIGQUIT이 block되어 있기 때문에 Ctrl+\ 을 눌러도 반응이 없다). Ctrl-c를 누르면 block되지 않은 signal 이므로 pause()를 빠져나오고 handler가 호출된다. 그리고 sigpending()에서 현재 pending 된 signal을 확인한다. Ctrl+c전에 Ctrl+\를 눌렀다면 SIGQUIT이 pending되었다고 나오게 된다. 그리고 마지막 두줄이 중요한데, sigsuspend(&amp;sigset_old) 를 호출하면 프로세스가 sigset_old에 있는 SIGQUIT signal이 일어나서 처리 될때까지 대기한다(때문에 SIGQUIT이 들어오지 않으면 계속 기다리고 있는다). sigsuspend 대신에 sigprocmask 로 UNBLOCK하면 그 순간 pending되어 있는 signal 이 프로세스에 전달되는데, pending 되어 있는 signal이 없으면 그냥 넘어간다. 즉 sigsuspend()를 쓰면 signal이 일어날때까지 기다리고, sigprocmask UNBLOCK을 쓰면 signal이 있을 때 handler가 호출되고 없으면 그냥 넘어가는 차이가 있다.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-2155819465360558048?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/2155819465360558048/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/05/signals-signal-block-with-masking.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/2155819465360558048'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/2155819465360558048'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/05/signals-signal-block-with-masking.html' title='Signals, signal block with masking'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-736608145061420810</id><published>2008-05-19T23:45:00.006+09:00</published><updated>2008-05-29T23:44:46.185+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='thread'/><title type='text'>Thread, Basic</title><content type='html'>LSP에서는 thread를 다루고 있지 않다. 그래서 APUE의 내용을 통해 복습해 보려고 한다. 알다시피 thread는 한 프로세스 내에서 여러개로 되어 동작하기 때문에 프로세스 내의 메모리나 fd를 공유한다. 그렇기 때문에 이러한 프로세스 내 공유 자원들에 접근할 때는 항상 consistency를 생각해야 한다. thread를 사용하는 일반적인 장점들은 아래와 같다.&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;asyncronous event를 다루는 루틴을 event type에 따라 별개의 thread를 만들어 처리하면 코드가 간단해진다.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;여러 프로세스들을 사용하면서 fd, memory를 공유하려면 복잡한 커널의 system call을 사용해야하는 반면에 thread에서는 간단하게 처리할 수 있다.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;한 thread에서 직렬로 진행되던 루틴들이 병렬화 되어 성능 향상을 가져올 수 있다.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Single processor에서도 성능향상이 있을 수 있다(한 thread가 block일때 다른 thread는 돌 수 있으므로)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;multiple thread를 사용하므로써 사용자 응답시간이 좋아진다(user input/output을 thread로 돌리면 되므로) .&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Multi-processor 환경에서 성능 향상을 가져다 준다.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;한개의 thread는 여러 정보들을 가지고 있는데 아래와 같다.&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;thread ID, 레지스터 값들, 스택, 스케쥴 priority, policy, signal mask and errno&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;소위 pthread라 불리는 것들은 POSIX.1-2001의 optional feature이다. 이게(optional한 부분이) 지원되는지 안되는지는 _POSIX_THREADS 를 #ifdef로 테스트 해보면 된다(아님, sysconf에서 _SC_THREADS로 호출해보거나..)&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;thread identification&lt;/strong&gt; pid_t 처럼 thread에서는 pthread_t 를 쓴다. 그런데, 구현에 따라 pthread_t를 구조체로 만드는 경우도 있기 때문에 tid1 == tid2 식으로 비교할 수는 없고 아래 함수를 사용한다. 자신의 tid를 보기 위해서는 pthread_self()를 사용한다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;pthread.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; pthread_equal(pthread_t tid1, pthread_t tid2);&lt;br /&gt;pthread_t pthread_self(&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;일단 thread 만드는 함수를 알아야 할텐데, 아래와 같다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;pthread.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; pthread_create(pthread_t *&lt;font color="#2e8b57"&gt;&lt;b&gt;restrict&lt;/b&gt;&lt;/font&gt; tidp, &lt;font color="#2e8b57"&gt;&lt;b&gt;const&lt;/b&gt;&lt;/font&gt; pthread_attr_t *&lt;font color="#2e8b57"&gt;&lt;b&gt;restrict&lt;/b&gt;&lt;/font&gt; attr, &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; *(*start_rtn)(&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;), &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; *&lt;font color="#2e8b57"&gt;&lt;b&gt;restrict&lt;/b&gt;&lt;/font&gt; arg);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;좀 어려워 보이지만 인자부터 체크해보자, 첫번째는 tid가 반환 될 것이고 두번째는 attributes를 넘겨줄 때 쓴다. 새로 생성된 thread는 start_rtn 루틴 부터 시행을 시작할 것이고, 이 함수는 arg를 인자로 받는다. thread는 signal mask를 상속받지만, pending 되어 있던 signal들은 clear된다. 조심할 점은 thread가 만들어지면 어떤 것이 먼저 실행될지 알 수 없다는 것이다. 대충 알았으니 한번 만들어보자.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;pthread.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;sys/types.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;unistd.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;stdio.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;pthread_t ntid;&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; * thr_func(&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; *arg)&lt;br /&gt;{&lt;br /&gt;    printf(&lt;font color="#ff00ff"&gt;&amp;quot;new thread id(&lt;/font&gt;&lt;font color="#6a5acd"&gt;%u&lt;/font&gt;&lt;font color="#ff00ff"&gt;)pid(&lt;/font&gt;&lt;font color="#6a5acd"&gt;%u&lt;/font&gt;&lt;font color="#ff00ff"&gt;)&lt;/font&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;,&lt;br /&gt;        (&lt;font color="#2e8b57"&gt;&lt;b&gt;unsigned&lt;/b&gt;&lt;/font&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;)pthread_self(), (&lt;font color="#2e8b57"&gt;&lt;b&gt;unsigned&lt;/b&gt;&lt;/font&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;)getpid());&lt;br /&gt;&lt;br /&gt;    &lt;font color="#804040"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt; (&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; *)&lt;font color="#ff00ff"&gt;0&lt;/font&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; main()&lt;br /&gt;{&lt;br /&gt;    &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; err;&lt;br /&gt;&lt;br /&gt;    err = pthread_create(&amp;amp;ntid, &lt;font color="#ff00ff"&gt;NULL&lt;/font&gt;, thr_func, &lt;font color="#ff00ff"&gt;NULL&lt;/font&gt;);&lt;br /&gt;    &lt;font color="#804040"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt; (err != &lt;font color="#ff00ff"&gt;0&lt;/font&gt;)&lt;br /&gt;        fprintf(&lt;font color="#ff00ff"&gt;stderr&lt;/font&gt;, &lt;font color="#ff00ff"&gt;&amp;quot;pthread_create error&lt;/font&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;);&lt;br /&gt;&lt;br /&gt;    printf(&lt;font color="#ff00ff"&gt;&amp;quot;main thread id(&lt;/font&gt;&lt;font color="#6a5acd"&gt;%u&lt;/font&gt;&lt;font color="#ff00ff"&gt;)pid(&lt;/font&gt;&lt;font color="#6a5acd"&gt;%u&lt;/font&gt;&lt;font color="#ff00ff"&gt;)&lt;/font&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;,&lt;br /&gt;        (&lt;font color="#2e8b57"&gt;&lt;b&gt;unsigned&lt;/b&gt;&lt;/font&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;)pthread_self(), (&lt;font color="#2e8b57"&gt;&lt;b&gt;unsigned&lt;/b&gt;&lt;/font&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;)getpid());&lt;br /&gt;    sleep(&lt;font color="#ff00ff"&gt;1&lt;/font&gt;);&lt;br /&gt;    &lt;font color="#804040"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt; &lt;font color="#ff00ff"&gt;0&lt;/font&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;linux에서는 pid가 다른 경우도 있고, tid는 4자리로 나타나는 것으로 되어 있는데, 실제 돌려보니 pid가 같고, tid도 연관성이 없는 것처럼 보인다(FreeBSD처럼 나온다) 왜일까. pthread_self 대신 gettid()를 사용하면 pid와 비슷하게 생긴 tid를 얻을 수 있다.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-736608145061420810?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/736608145061420810/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/05/thread-basic.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/736608145061420810'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/736608145061420810'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/05/thread-basic.html' title='Thread, Basic'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-8965180055071902097</id><published>2008-05-16T09:31:00.003+09:00</published><updated>2008-05-21T00:15:39.249+09:00</updated><title type='text'>Signals, signal set</title><content type='html'>편리하게, 여러 signal을 묶어서 처리할 수 있다. 묶어진 signal set을 통해 특정 signal들을 block하거나, block을 통해 pending된 signal을 처리하고 혹은 특정 signal들을 기다리는 것도 가능하다. 조작에 쓰이는 기본적인 함수들은 아래와 같다.&lt;br/&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;signal.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; sigemptyset(sigset_t *set);&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; sigfillset(sigset_t *set);&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; sigaddset(sigset_t *set, &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; signo);&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; sigdelset(sigset_t *set, &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; signo);&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; sigismember(&lt;font color="#2e8b57"&gt;&lt;b&gt;const&lt;/b&gt;&lt;/font&gt; sigset_t *set, &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; signo);&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; sigisemptyset(sigset_t *set);&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; sigorset(sigset_t *dest, sigset_t *left, sigset_t *right);&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; sigandset(sigset_t *dest, sigset_t *left, sigset_t *right);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;sigset_t 는 signal들을 bit에 하나씩 맵핑시킨 것인데, sigemptyset은 이를 0으로 AND 시키고, sigfullset 은 0xF...F 로 OR 시킨다고 생각하면된다. sigandset 은 left, right를 and해서 dest에 넘겨주고, sigorset은 OR한다. 나머지 함수들은 직관적이므로 생략.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-8965180055071902097?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/8965180055071902097/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/05/signals-signal-set.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/8965180055071902097'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/8965180055071902097'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/05/signals-signal-set.html' title='Signals, signal set'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-1966032717222730388</id><published>2008-05-16T09:20:00.003+09:00</published><updated>2008-05-23T09:16:43.860+09:00</updated><title type='text'>Signals, reentrancy</title><content type='html'>signal을 처리하고 있는데 다른 signal이 들어와서 중간에 다른 루틴을 수행한다면? 그 과정이 계속 반복된다면? 혼란스러운 일이다. 그래서 signal을 처리할 때는 이를 약간 고려해줘야한다. global 데이터는 손데지 않고, shared data도 안건드리는 것은, 좋은 습관이다. handler에서 malloc()을 호춣거나 strsignal()과 같이 static buffer를 사용하는 경우 중간에 들어오는 signal에 대해 어떻게 처리될지 알아두는 것은 좋은 일이다. reentrant function 이라함은 같은 프로세스내의 다른 thread에 의해 호출되어도 '안전'한 경우를 말한다. 이를 위해서는 아래 내용들이 지켜져야한다.&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;static data를 조작하면 안되고,&lt;/li&gt;&lt;br /&gt;&lt;li&gt;stack에 있는 데이터나 caller가 준 데이터만 조작한다&lt;/li&gt;&lt;br /&gt;&lt;li&gt;다른 nonreentrant function을 호출하지 않는다,&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;재진입가능한 함수들에 대해서는 ... 종류가 많은데 필요하면 그때 책을 참조하는 것으로 하자. 일반적으로 abort, bind, connect, fork, fsync, kill, read, send, signal, time, wait, open, pipe, select, poll, recv, sock 등은 reentrant하지만, malloc 등은 그렇지 않다.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-1966032717222730388?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/1966032717222730388/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/05/signals-reentrancy.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/1966032717222730388'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/1966032717222730388'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/05/signals-reentrancy.html' title='Signals, reentrancy'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-8725807478845175832</id><published>2008-05-14T23:34:00.005+09:00</published><updated>2008-05-23T09:11:11.895+09:00</updated><title type='text'>Signals, basic manipulation</title><content type='html'>아주 기초, 기본적인 signal 처리함수는 아래와 같다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;signal.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;typedef&lt;/b&gt;&lt;/font&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; (*sighandler_t)(&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;);&lt;br /&gt;sighandler_t signal(&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; signo, sighandler_t handler);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;signo에 해당하는 signal이 발생할 때 handler 함수를 호출하겠다는 얘기다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#ff80ff"&gt;#include &lt;/font&gt;&lt;font color="#ffa0a0"&gt;&amp;lt;stdio.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ff80ff"&gt;#include &lt;/font&gt;&lt;font color="#ffa0a0"&gt;&amp;lt;signal.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#60ff60"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; handle_sigtstp(&lt;font color="#60ff60"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; signal)&lt;br /&gt;{&lt;br /&gt;    printf(&lt;font color="#ffa0a0"&gt;&amp;quot;ctrl-z pressed. &amp;quot;&lt;/font&gt;&lt;br /&gt;        &lt;font color="#ffa0a0"&gt;&amp;quot;You shouldn't use printf!&lt;/font&gt;&lt;font color="#ffa500"&gt;\n&lt;/font&gt;&lt;font color="#ffa0a0"&gt;&amp;quot;&lt;/font&gt;);&lt;br /&gt;    &lt;font color="#ffff60"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;font color="#60ff60"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; main()&lt;br /&gt;{&lt;br /&gt;    signal(&lt;font color="#ffa0a0"&gt;SIGTSTP&lt;/font&gt;, handle_sigtstp);&lt;br /&gt;&lt;br /&gt;    sleep(&lt;font color="#ffa0a0"&gt;10&lt;/font&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;위 예제 처럼 간단하게 등록, 사용할 수 있다. printf 같은 함수를 호출하면 안되는 이유는 이 함수가 reentrancy를 보장하기 않기 때문인데, 일단 나중에 얘기하자.&lt;br/&gt;&lt;br /&gt;사용자 handler 대신에 default로 동작하기를 원하는경우 handler 대신 'SIG_DFL'을 주면 되고, signal을 무시하고자 하는 경우에는 SIG_IGN을 주면된다. signal()은 등록된 handler의 포인터나 SIG_DFL, SIG_IGN 을 주는데, 실패한 경우 SIG_ERR을 준다(errno를 설정하지는 않는다)&lt;br /&gt;&lt;br /&gt;signal을 테스트할 때 편한 함수로 pause()가 있다(signal을 받을 때 까지 기다린다). 이러한 부분을 고려하면 코드는 아래와 같아진다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#804040"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt;(signal(&lt;font color="#ff00ff"&gt;SIGINT&lt;/font&gt;, handler) == &lt;font color="#ff00ff"&gt;SIG_ERR&lt;/font&gt;) {&lt;br /&gt;        fprintf(&lt;font color="#ff00ff"&gt;stderr&lt;/font&gt;, &lt;font color="#ff00ff"&gt;&amp;quot;Can't handle SIGINT&lt;/font&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;프로세스가 실행(exec)되면 Signal handle은 default로 잡힌다. 부모 프로세스가 특정 signal을 무시하고 있었다면, exec된 프로세스도 무시하게 된다. 그리고 부모 프로세스가 잡아서 처리하던 signal은 default action으로 바뀐다(부모 프로세스의 주소공간을 공유하고 있지 않아서 handler도 공유/상속되지 않기 때문이다). &lt;br /&gt;&lt;br /&gt;쉘에서 특정 job을 bg로 돌리는 경우 bg로 돌아가는 job은 SIGINT, SIGQUIT 등을 무시해야 한다. 그래서 쉘에서 bg job들을 실행하기 전에 아래처럼 SIGINT, SIGQUIT을 무시하는 코드를 수행한다(그래야 bg job들도 무시하게 되니까)&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#804040"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt;(signal(&lt;font color="#ff00ff"&gt;SIGINT&lt;/font&gt;, &lt;font color="#ff00ff"&gt;SIG_IGN&lt;/font&gt;) != &lt;font color="#ff00ff"&gt;SIG_IGN&lt;/font&gt;) {&lt;br /&gt;        &lt;font color="#804040"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt;(signal(&lt;font color="#ff00ff"&gt;SIGINT&lt;/font&gt;, sight_handler) == &lt;font color="#ff00ff"&gt;SIG_ERR&lt;/font&gt;) {&lt;br /&gt;                fprintf(&lt;font color="#ff00ff"&gt;stderr&lt;/font&gt;, &lt;font color="#ff00ff"&gt;&amp;quot;Can't handle SIGINT&lt;/font&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;);&lt;br /&gt;        }&lt;br /&gt;}&lt;br /&gt;&lt;font color="#0000ff"&gt;/*&lt;/font&gt;&lt;font color="#0000ff"&gt; SIGQUIT도 마찬가지 &lt;/font&gt;&lt;font color="#0000ff"&gt;*/&lt;/font&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;그런데 fork()의 경우에는 좀 다르다. 부모의 주소공간을 공유하기 때문에 signal handler 까지 모두 받아서 똑같이 signal을 처리한다.&lt;br/&gt;&lt;br /&gt;특정 signal이 발생했을 때 SIGINT인지 SIGKILL인지 숫자로 되어있어 햇갈릴 수 있다. 그래서  sys_siglist[] 를 통해서 각각 signal을 string으로 찍어볼 수 있다. linux에서 char *strsignal(int signo)를 제공하지만 표준은 아니다(thread-safe하지도 않다). sys_siglist[]를 추천한다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;signal.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;stdio.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; sig_handler(&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; signo)&lt;br /&gt;{&lt;br /&gt;        printf(&lt;font color="#ff00ff"&gt;&amp;quot;signal caught : &lt;/font&gt;&lt;font color="#6a5acd"&gt;%s&lt;/font&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;, sys_siglist[signo]);&lt;br /&gt;        &lt;font color="#804040"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; main()&lt;br /&gt;{&lt;br /&gt;        &lt;font color="#804040"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt; (signal(&lt;font color="#ff00ff"&gt;SIGINT&lt;/font&gt;, sig_handler) == &lt;font color="#ff00ff"&gt;SIG_ERR&lt;/font&gt;) {&lt;br /&gt;                fprintf(&lt;font color="#ff00ff"&gt;stderr&lt;/font&gt;, &lt;font color="#ff00ff"&gt;&amp;quot;SIGINT handle can't be registered&lt;/font&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;);&lt;br /&gt;        }&lt;br /&gt;        pause();&lt;br /&gt;        &lt;font color="#804040"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;signal을 보내는 방법은 아래처럼 매우 간단하다. 혹은 kill로 바로 보내도 된다(like, kill -HUP [pid]).&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;sys/types.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;signal.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; kill(pid_t pid, &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; signo);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;kill()은 세가지 값을 반환하는데, invalid signal인 경우 EINVAL, 권한이 없는 경우 EPERM, pid가 없거나 좀비인 경우 ESRCH이다.&lt;br/&gt;&lt;br /&gt;다른 user나 그룹등...에 signal을 보내고자 하는 경우에는 프로세스가 CAP_KILL capability가 있어야 한다. 내가 다른 프로세스에 signal을 보낼 권한이 있는지 체크하는 좋은 방법으로는 signal로 '0'을 보내보는 것이다(실제 signal을 보내지는 않으므로 err만 체크할 수 있다).&lt;br/&gt;&lt;br /&gt;자기자신에게 signal을 보낼 때는 간단히 raise()를 사용한다(like, int raise(int signo)). 이것은 kill(getpid(), signo) 와 같다. 전체 프로세스 그룹에 보내는 경우에는 killpg(int pgrp, int signo)를 사용한다(kill을 사용해서 kill(int -pgrp, signo)처럼 해도된다). pgrp = 0 이면 자신이 띄운 프로세스들에 모두 보낸다.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-8725807478845175832?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/8725807478845175832/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/05/signals-basic-manipulation.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/8725807478845175832'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/8725807478845175832'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/05/signals-basic-manipulation.html' title='Signals, basic manipulation'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-7543166641724825415</id><published>2008-05-14T22:19:00.003+09:00</published><updated>2008-05-14T23:34:18.120+09:00</updated><title type='text'>Signals, brief</title><content type='html'>&lt;strong&gt;Signal&lt;/strong&gt;은 비동기적인 이벤트를 핸들링하는 매커니즘을 제공하는 Software Interrupt이다. Signal은 IPC의 원시적인 형태라고 봐도 된다. Unix의 역사상 Signal의 구현은 여러 갈래로 나누어 지려 했으나, 다행히 POSIX에서 표준을 제공하고, 이를 Linux에서 제공하고 있다.&lt;br/&gt;&lt;br /&gt;일단 Signal이 발생하면 커널은 전달 가능한 상태가 될 때까지 기다렸다가 이를 해당 프로세스에 전달해준다. Signal의 처리는 아래 세가지 방식으로 진행된다.&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;무시한다.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;잡아서 처리한다.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Default로 처리되게 둔다.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;Signal 관련 함수들은 signal.h 에 정의되어 있고, kill()함수를 통해 보낼 수 있다. 쉘에서도 kill 을 통해 보낼 수 있으며, -l옵션으로 그 종류를 볼 수 있다. 각각의 signal을 간략히 정리해보면,&lt;br/&gt;&lt;br /&gt;&lt;strong&gt;SIGABRT&lt;/strong&gt; 코어내고 종료. assert(), abort() 호출시 이 signal 발생&lt;br/&gt;&lt;br /&gt;&lt;strong&gt;SIGALRM&lt;/strong&gt; alarm(), setitimer() with ITIMER_REAL&lt;br/&gt;&lt;br /&gt;&lt;strong&gt;SIGBUS&lt;/strong&gt; 이전에는 비메모리 시스템 에러였는데, 지금은 mmap()안된 영역 접근시 발생한다.&lt;br/&gt;&lt;br /&gt;&lt;strong&gt;SIGCHLD&lt;/strong&gt; default로는 무시되나, wait() 호출시 child 종료되면 발생&lt;br/&gt;&lt;br /&gt;&lt;strong&gt;SIGCONT&lt;/strong&gt; 프로세스 중단 후 재시작시 발생. 터미널, 에디터에서 refresh위해 사용함&lt;br/&gt;&lt;br /&gt;&lt;strong&gt;SIGFPE&lt;/strong&gt; floating point 관련 에러&lt;br/&gt;&lt;br /&gt;&lt;strong&gt;SIGHUP&lt;/strong&gt; 세션 종료시 발생. 많은 daemon 프로그램에서 이를 사용해서 conf 파일을 다시 읽게 함(convention) 예. apache에서 SIGHUP 받으면 httpd.conf 읽음&lt;br/&gt;&lt;br /&gt;&lt;strong&gt;SIGILL&lt;/strong&gt; illegal machine instruction&lt;br/&gt;&lt;br /&gt;&lt;strong&gt;SIGINT&lt;/strong&gt; Ctrl-C&lt;br/&gt;&lt;br /&gt;&lt;strong&gt;SIGKILL&lt;/strong&gt; &lt;br/&gt;&lt;br /&gt;&lt;strong&gt;SIGPIPE&lt;/strong&gt; PIPE 만들어 쓰고 있는데, 받는쪽이 종료한 경우 발생. default로는 종료됨&lt;br/&gt;&lt;br /&gt;&lt;strong&gt;SIGPROF&lt;/strong&gt; profiling timer expires (setitimer() with ITIMER_PROF)&lt;br/&gt;&lt;br /&gt;&lt;strong&gt;SIGPWR&lt;/strong&gt; low-bat, UPS system -&gt; init process -&gt; system terminate&lt;br/&gt;&lt;br /&gt;&lt;strong&gt;SIGQUIT&lt;/strong&gt; Ctrl-\ 모든 foreground 프로세스에게 전달. (코어 후 종료)&lt;br/&gt;&lt;br /&gt;&lt;strong&gt;SIGSEGV&lt;/strong&gt; Segmentation Violation&lt;br/&gt;&lt;br /&gt;&lt;strong&gt;SIGSTOP&lt;/strong&gt; kill에의해서만 보내질 수 있음. (무시안됨)&lt;br/&gt;&lt;br /&gt;&lt;strong&gt;SIGSYS&lt;/strong&gt; invalid system call (최신 바이너리를 오래된 커널에서 돌리지 않는 이상 거의 일어날 일이 없음)&lt;br/&gt;&lt;br /&gt;&lt;strong&gt;SIGTERM&lt;/strong&gt; 바로 종료 (이걸 catch 하면 manner 없음 ㅡ.ㅡ;)&lt;br/&gt;&lt;br /&gt;&lt;strong&gt;SIGTRAP&lt;/strong&gt; when it cross breakpoint&lt;br/&gt;&lt;br /&gt;&lt;strong&gt;SIGTSTP&lt;/strong&gt; Ctrl-z&lt;br/&gt;&lt;br /&gt;&lt;strong&gt;SIGTTIN, SIGTTOU&lt;/strong&gt; bg job 들이 읽거나 쓰려고 하는 경우 발생&lt;br/&gt;&lt;br /&gt;&lt;strong&gt;SIGURG&lt;/strong&gt; 소켓에 OOB(out of band) 데이터 들어오면 발생&lt;br/&gt;&lt;br /&gt;&lt;strong&gt;SIGUSR1 SIGUSR2&lt;/strong&gt; user-defined purpose&lt;br/&gt;&lt;br /&gt;&lt;strong&gt;SIGVTALRM&lt;/strong&gt; setitimer() 관련 signal&lt;br/&gt;&lt;br /&gt;&lt;strong&gt;SIGWINCH&lt;/strong&gt; terminal window 값이 바뀐 경우 발생(예, top해놓고 터미널 사이즈를 조절할 때 화면 refresh를 위해 발생). &lt;br/&gt;&lt;br /&gt;&lt;strong&gt;SIGXCPU&lt;/strong&gt; 프로세스가 soft processor limit를 초과할 때 발생 (1초에 한번씩 계속.. hard limit까지 넘으면, SIGKILL받고 죽음)&lt;br/&gt;&lt;br /&gt;&lt;strong&gt;SIGXFSZ&lt;/strong&gt; process가 file size limit을 넘을 때 발생&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-7543166641724825415?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/7543166641724825415/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/05/signals.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/7543166641724825415'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/7543166641724825415'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/05/signals.html' title='Signals, brief'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-507374328678164060</id><published>2008-05-09T10:28:00.002+09:00</published><updated>2008-05-09T10:43:18.071+09:00</updated><title type='text'>Memory, Opportunistic Allocation</title><content type='html'>linux는 opportunistic allocation을 사용한다. 프로세스가 메모리 할당을 추가로 요구하면 바로 commit 해주지만 실제로 할당은 안되어 있다. 프로세스가 할당되어 있다고 생각한 이 영역에 뭔가를 쓰려고 하면 그때야 비로소 메모리를 할당해주는데 여기에는 demand paging, cow 등이 사용될 수 있다.&lt;br /&gt;&lt;br /&gt;이런식의 메모리 할당은 실제 필요한 메모리만 할당해줄 수 있어 공간 효율적이고, 할당 작업을 실제 필요할 때까지 늦출 수 있으며, 실제 가능한 공간 이상으로 할당 해줄 수도 있다(overcommitment)&lt;br /&gt;&lt;br /&gt;경우에 따라서 가용한 메모리 공간 보다 더 큰 영역을 할당해달라고 요청하는 프로세스들도 있는데, 커널에서 이를 수용하는 것을 overcommitment라고 한다. 이렇게 overcommitment되어 잘사용되면 다행이고, 진짜로 실제 메모리 이상을 사용하게 되면 OOM (out of memory)에러를 내어 OOM Killer가 해당 프로세스를 종료시키므로, 전체 동작에는 지장이 없다. overcommit 에도 옵션이 있는데, /proc/sys/vm/overcommit_memory 의 값을 통해 조정할 수 있다 (혹은 sysctl의 vm.overcommit_memory).&lt;br /&gt;&lt;br /&gt;값이 0인 경우 휴리스틱한 overcommitment를 허용해주고, 1인경우 모든 요청을 허용해준다. 2인 경우에는 overcommitment를 disable하고 strict accounting을 enable하는데, 메모리 할당이 스왑영역 + 물리적 메모리의 일정 비율부분 까지로 제한된다. 일정 비율 부분은 /proc/sys/vm/overcommit_ratio에 정의되어 있는데, 이 값이 50인경우(default) 할당 가능한 메모리 공간은 스왑크기 + 물리적 메모리 크기의 50% 이다. &lt;br /&gt;&lt;br /&gt;OOM Killer에 의해 프로세스가 죽는 것을 원치 않기 때문에 strict accounting을 하려고 하지만, 이게 만병통치약은 아니다. ( 가상 메모리는 대부분의 프로세스가 필요이상의 메모리를 할당하여 동작하려한다는 패턴에 기초하여 제공되는 메커니즘인데, 이를 사용하지 않겠다는 것이기 때문이다 )&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-507374328678164060?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/507374328678164060/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/05/memory-opportunistic-allocation.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/507374328678164060'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/507374328678164060'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/05/memory-opportunistic-allocation.html' title='Memory, Opportunistic Allocation'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-3509157889966405101</id><published>2008-05-09T10:10:00.002+09:00</published><updated>2008-05-09T10:28:23.164+09:00</updated><title type='text'>Memory, Locking</title><content type='html'>알다시피 Linux는 demang paging(필요하면 그때 swap in 해주고 안쓰면 디스크로 다시 swap out하는) 이다. 그래서 실제 가지고 있는 물리적 메모리 공간 보다 더 큰 공간을 가상으로 제공해준다. 하지만, 경우에 따라서 자신의 메모리가 디스크로 swap out 되면 안되는 경우도 있다.&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;Determinism&lt;/strong&gt; 특정 메모리에 올라가 있는 루틴이 일정시간내에 반드시 끝나야 하는 경우이다. 디스크에 swap out 되어 있으면 swap in 하는데 걸리는 시간이 상당하므로 정해진 시간에 응답하지 못할 수도 있다.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;Security&lt;/strong&gt;암호화된 비밀 정보를 디스크에서 읽어 복호화 한다음 메모리에 가지고 있었는데, 이 영역이 swap out되면 디스크에 복호화된 비밀정보가 남아 보안상의 취약점이 될 수 있다.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;그래서 메모리의 일정 부분은 swap out 되지 않도록 잠글 수 있는데, 이 때 사용되는 함수가 mlock() 이다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;sys/mman.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; mlock(&lt;font color="#2e8b57"&gt;&lt;b&gt;const&lt;/b&gt;&lt;/font&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; *addr, &lt;font color="#2e8b57"&gt;&lt;b&gt;size_t&lt;/b&gt;&lt;/font&gt; len);&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; mlockall(&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; flags);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;그 외에 특정 프로세스의 모든 부분을 locking 하고싶은 경우에는 mlockall()을 사용하면 된다. mlockall()에서 사용되는 flag으로는 아래 두가지가 있는데 일반적으로 두개를 다 OR해서 사용한다.&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;MCL_CURRENT&lt;/strong&gt; 현재 프로세스가 사용하는 모든 메모리를 lock&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;MCL_FUTURE&lt;/strong&gt; 앞으로 사용할 메모리까지도 lock&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;lock된 메모리의 해제는 munlock(), munlockall(void)을 통해 진행하면 된다. CAP_IPC_LOCK이 설정된 경우에는 무한정으로 메모리를 잠글 수 있지만, 그렇지 않은 경우에는 RLIMIT_MEMLOCK 에 설정된 바이트 까지만 locking할 수 있다. (default로 32KB 이다)&lt;br /&gt;&lt;br /&gt;특정 페이지가 디스크에 있는지, 메모리에 있는지를 확인하는 함수로 mincore()가 있다. 아래와 같은데, 이 함수는 bit vector 형식으로 페이지의 메모리/디스크 상주 여부를 리턴해준다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;sys/mman.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;unistd.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; mincore(&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; *start,&lt;br /&gt;        &lt;font color="#2e8b57"&gt;&lt;b&gt;size_t&lt;/b&gt;&lt;/font&gt; length,&lt;br /&gt;        &lt;font color="#2e8b57"&gt;&lt;b&gt;unsigned&lt;/b&gt;&lt;/font&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;char&lt;/b&gt;&lt;/font&gt; *vec);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;안따깝게도 이 함수는 MAP_SHARED 옵션으로 mmap 맵핑된(실제 파일에) 영역에 대해서만 정상적으로 동작한다.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-3509157889966405101?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/3509157889966405101/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/05/memory-locking.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/3509157889966405101'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/3509157889966405101'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/05/memory-locking.html' title='Memory, Locking'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-6511937120059699299</id><published>2008-04-30T09:54:00.002+09:00</published><updated>2008-04-30T10:11:31.897+09:00</updated><title type='text'>Manipulating Memory</title><content type='html'>메모리를 다루는 여러 함수들을 살짝 다루고 넘어가자.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;특정 값으로 초기화&lt;/strong&gt; 는 memset을 사용한다. BSD에서는 bzero를 사용하기도 한다. malloc 한 후 memset 하는 짓... 하지 말고 그냥 calloc() 을 사용하는 것이 함수 호출도 줄이고, 코드도 짧아지고, 성능도 향상된다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;string.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; * memset(&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; *s, &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; c, &lt;font color="#2e8b57"&gt;&lt;b&gt;size_t&lt;/b&gt;&lt;/font&gt; n);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;strong&gt;메모리 비교하기&lt;/strong&gt; 는 memcmp를 쓰면된다. 마찬가지로 BSD에서는 bcmp를 지원한다. 주의할 것은 구조체의 경우 패딩값으로 쓰레기 값들이 들어갈 수 있어서 구조체의 비교를 memcmp로 하면 안된다(같아도 다른 값이 나올 수 있기 때문이다). 구조체는 해당 값들을 일일이, 직접 비교해줘야 한다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;string.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; memcmp (&lt;font color="#2e8b57"&gt;&lt;b&gt;const&lt;/b&gt;&lt;/font&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; *s1, &lt;font color="#2e8b57"&gt;&lt;b&gt;const&lt;/b&gt;&lt;/font&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; *s2, &lt;font color="#2e8b57"&gt;&lt;b&gt;size_t&lt;/b&gt;&lt;/font&gt; n);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;strong&gt;메모리 복사(이동)&lt;/strong&gt; 은 memmove 와 좀더 친근한 memcpy가 있다. 둘간에 차이가 있는데, memmove는 src, dst 공간의 overlap을 허용한다는 것과, memcpy는 overlap되는 경우 동작이 unknown이라는 거다. overlap된 메모리의 데이터를 변환할거라면 구지 이런 함수들 쓰지 말고 포인터로 직접 해줘야 겠다. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;string.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; * memmove(&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; * dst, &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; * src, &lt;font color="#2e8b57"&gt;&lt;b&gt;size_t&lt;/b&gt;&lt;/font&gt; n);&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; * memcpy(&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; * dst, &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; * src, &lt;font color="#2e8b57"&gt;&lt;b&gt;size_t&lt;/b&gt;&lt;/font&gt; n);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;그외에도 특정 문자가 나타날 때까지만 복사하는 memccpy(*dst, *src, size) 가 있고, 특정 바이트를 찾는 memchr 가 있다(memrchr은 GNU에서 제공하는 것인데, 뒤에서부터 꺼꾸로 찾는다).&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;string.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; * memchr(&lt;font color="#2e8b57"&gt;&lt;b&gt;const&lt;/b&gt;&lt;/font&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; *s, &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; c, &lt;font color="#2e8b57"&gt;&lt;b&gt;size_t&lt;/b&gt;&lt;/font&gt; n);&lt;br /&gt;&lt;font color="#a020f0"&gt;#define _GNU_SOURCE&lt;/font&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; * memrchr(&lt;font color="#0000ff"&gt;/*&lt;/font&gt;&lt;font color="#0000ff"&gt; same as above&lt;/font&gt;&lt;font color="#0000ff"&gt;*/&lt;/font&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;그리고 haystack에서 needle을 찾는 함수 (일종의 strstr...?) memmem도 있다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#define _GNU_SOURCE&lt;/font&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;string.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; * memmem(&lt;font color="#2e8b57"&gt;&lt;b&gt;const&lt;/b&gt;&lt;/font&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; *haystack,&lt;br /&gt;                &lt;font color="#2e8b57"&gt;&lt;b&gt;size_t&lt;/b&gt;&lt;/font&gt; hatstacklen,&lt;br /&gt;                &lt;font color="#2e8b57"&gt;&lt;b&gt;const&lt;/b&gt;&lt;/font&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; *needle,&lt;br /&gt;                &lt;font color="#2e8b57"&gt;&lt;b&gt;size_t&lt;/b&gt;&lt;/font&gt; needlelen);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;조금 희한한 함수로, 무조건 '42'와 XOR 해서 넘겨주는 memfrob이 있는데, 두번 XOR하면 원래 것이 나오므로, 임시로 데이터를 희끄므리 ... 하게 하고 싶을 때 쓴다(아마도 encryption이 중시되지 않을 때 만든 것인듯).&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#define _GNU_SOURCE&lt;/font&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;string.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; * memfrob(&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; *s, &lt;font color="#2e8b57"&gt;&lt;b&gt;size_t&lt;/b&gt;&lt;/font&gt; n);&lt;br /&gt;memfrob(memfrob(text, len), len); &lt;font color="#0000ff"&gt;// same!&lt;/font&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-6511937120059699299?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/6511937120059699299/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/04/manipulating-memory.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/6511937120059699299'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/6511937120059699299'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/04/manipulating-memory.html' title='Manipulating Memory'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-8492463636604156532</id><published>2008-04-30T09:48:00.002+09:00</published><updated>2008-04-30T09:54:52.806+09:00</updated><title type='text'>Memory Allocation Mechanism</title><content type='html'>메모리를 할당하는 여러가지 방법들이 있는데, 각각의 장단점을 생각해보자.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;malloc&lt;/strong&gt; 일반적인데, 초기화 안된다.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;calloc&lt;/strong&gt; 0으로 초기화 되나 malloc보단 조금 복잡하다&lt;/li&gt;&lt;li&gt;&lt;strong&gt;realloc&lt;/strong&gt; resize&lt;/li&gt;&lt;li&gt;&lt;strong&gt;brk, sbrk&lt;/strong&gt; 아주,.. low level 하다.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Anonymous Memory Mappings&lt;/strong&gt; 큰 공간 할당시 유용하고, 쉽고, 공유가능하다. 작은 공간 사용시에는 낭비가 있다(페이지 단위로 할당하니까... 맞나 ㅡ.ㅡ;).&lt;/li&gt;&lt;li&gt;&lt;strong&gt;posix_memalign&lt;/strong&gt; align이 중요할때만 사용...&lt;/li&gt;&lt;li&gt;&lt;strong&gt;alloca&lt;/strong&gt; 스택에서 할당.  편리. 해제할 필요없음. 큰 공간할당에는 부적절. 안되는 시스템도 있고..&lt;/li&gt;&lt;li&gt;&lt;strong&gt;VLA&lt;/strong&gt; scope 내에서 할당 가능. 배열인 경우만 유용. &lt;/li&gt;&lt;/ul&gt;&lt;p&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-8492463636604156532?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/8492463636604156532/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/04/memory-allocation-mechanism.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/8492463636604156532'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/8492463636604156532'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/04/memory-allocation-mechanism.html' title='Memory Allocation Mechanism'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-7615338462459694470</id><published>2008-04-30T09:43:00.003+09:00</published><updated>2008-04-30T09:48:00.825+09:00</updated><title type='text'>VLA Variable Length Array</title><content type='html'>C99에서 도입한 것으로 VLA - 가변 길이 배열이 있다. 알다시피 일반적인 배열은 compile time에 해당 영역이 고정된다. 그러나 함수안에서 가변으로 배열을 선언하면 VLA로 잡히는데, (확실치는 않지만) 스택에 잡힌다. 아래와 같이 VLA를 사용할 수 있다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#804040"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/font&gt; (i = &lt;font color="#ff00ff"&gt;0&lt;/font&gt;; i &amp;lt; n; ++i) {&lt;br /&gt;        &lt;font color="#2e8b57"&gt;&lt;b&gt;char&lt;/b&gt;&lt;/font&gt; foo[i+&lt;font color="#ff00ff"&gt;1&lt;/font&gt;];&lt;br /&gt;        &lt;font color="#0000ff"&gt;/*&lt;/font&gt;&lt;font color="#0000ff"&gt; ... &lt;/font&gt;&lt;font color="#0000ff"&gt;*/&lt;/font&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;거의 둘이 흡사하나, alloca와 VLA가 다른 점이 있다. alloca로 스택에 잡은 메모리는 함수가 리턴하는 시점에 해제되지만, VLA의 경우는 위 코드와 같이 for loop을 벋어나는 순간, 즉 scope를 벗어나는 순간 해제 된다(위의 경우에 alloca를 사용한다면 loop을 도는 수만큼 공간을 사용했을 것이다).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-7615338462459694470?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/7615338462459694470/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/04/vla-variable-length-array.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/7615338462459694470'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/7615338462459694470'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/04/vla-variable-length-array.html' title='VLA Variable Length Array'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-9156689865921636089</id><published>2008-04-30T09:30:00.002+09:00</published><updated>2008-04-30T09:42:58.549+09:00</updated><title type='text'>alloca() : Allocating memory from the stack</title><content type='html'>스택은 프로그램의 자동변수들이 들어있는 공간이다. heap말고 이 스택에서 메모리를 할당받으려면 alloca()를 사용하면 된다. 스택에서 메모리를 할당받을 때의 장점은 별도의 메모리 해제가 필요없다는 것이다. 함수가 종료되면 메모리는 자동으로 해제된다. 왜? 스택에 있으니까. alloca()는 에러를 반환하지 않는다. 스택 메모리 할당의 실패는 stack overflow로 처리되기 때문이다.  아래와 같이 함수내에서 간단한 스트링 처리를 위해 사용하는 것이 일반적이다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;alloca.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; func(&lt;font color="#2e8b57"&gt;&lt;b&gt;const&lt;/b&gt;&lt;/font&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;char&lt;/b&gt;&lt;/font&gt;* tail) {&lt;br /&gt;        &lt;font color="#2e8b57"&gt;&lt;b&gt;const&lt;/b&gt;&lt;/font&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;char&lt;/b&gt;&lt;/font&gt; *str = &lt;font color="#ff00ff"&gt;&amp;quot;temporal string&amp;quot;&lt;/font&gt;;&lt;br /&gt;        &lt;font color="#2e8b57"&gt;&lt;b&gt;char&lt;/b&gt;&lt;/font&gt; * fullstr;&lt;br /&gt;&lt;br /&gt;        fullstr = alloca(strlen(tail)+strlen(str)+&lt;font color="#ff00ff"&gt;1&lt;/font&gt;);&lt;br /&gt;        strcpy(fullstr, str);&lt;br /&gt;        strcat(fullstr, tail);&lt;br /&gt;&lt;br /&gt;        &lt;font color="#0000ff"&gt;/*&lt;/font&gt;&lt;font color="#0000ff"&gt; do something &lt;/font&gt;&lt;font color="#0000ff"&gt;*/&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;        &lt;font color="#804040"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt; &lt;font color="#ff00ff"&gt;0&lt;/font&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;주의할 사항은 이렇게 alloca로 할당된 메모리 영역을 함수 호출시에 인자로 사용해서는 안된다는 것이다. (다른 함수 호출시 alloca로 할당 받은 스택 영역은 push 되니까!) 그리고 alloca()는 그다지 portable하지 않으므로 사용에 주의할 필요가 있다. 그러나 메모리 해제가 필요 없다는 점, 할당시 malloc에 비해 오버헤드가 적다는 점에서 자주 사용할 수 있는 유용한 함수이다. &lt;br /&gt;&lt;br /&gt;스트링을 스택 메모리에 복사해서 사용하는 경우도 있는데, 이를 위해서 Linux에서 제공하는 함수로 아래와 같은 것들이 있다(POSIX에서는 제공하지 않는다)&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#define _GNU_SOURCE&lt;/font&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;string.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;char&lt;/b&gt;&lt;/font&gt; * strdupa(&lt;font color="#2e8b57"&gt;&lt;b&gt;const&lt;/b&gt;&lt;/font&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;char&lt;/b&gt;&lt;/font&gt; *s);&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;char&lt;/b&gt;&lt;/font&gt; * strndupa(&lt;font color="#2e8b57"&gt;&lt;b&gt;const&lt;/b&gt;&lt;/font&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;char&lt;/b&gt;&lt;/font&gt; *s, &lt;font color="#2e8b57"&gt;&lt;b&gt;size_t&lt;/b&gt;&lt;/font&gt; n);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;예상되다시피 스트링을 스택 메모리에 복사한 후 포인터를 넘겨준다.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-9156689865921636089?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/9156689865921636089/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/04/alloca-allocating-memory-from-stack.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/9156689865921636089'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/9156689865921636089'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/04/alloca-allocating-memory-from-stack.html' title='alloca() : Allocating memory from the stack'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-6064281814990358197</id><published>2008-04-28T09:41:00.004+09:00</published><updated>2008-04-28T09:52:30.460+09:00</updated><title type='text'>Memory, advanced memory allocation</title><content type='html'>메모리 할당과 관련된 커널의 제한 값은 mallopt()를 통해 변경할 수 있다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;malloc.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; mallopt(&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; param, &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; value);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;자세한 옵션값은 ... 넘어가자 ㅡ.ㅡ; &lt;br /&gt;&lt;br /&gt;glibc에서 할당된 메모리는 실제보다 클수도 있다. 그래서 실제로 할당된 메모리 사이즈를 malloc_usable_size(void *ptr)를 통해 확인할 수 있다. 또 malloc_trim(size_t padding)함수를 사용하면 padding공간으로 있던 영역을 해제하여 여분의 메모리를 (아주 조금 이겠지만) 확보하는데 일반적으로 이런 과정은 자동으로 이루어진다.&lt;br /&gt;&lt;br /&gt;메모리를 디버깅할 때는 MALLOC_CHECK_ 환경 변수를 사용할 수 있다. 아래 처럼 이 값을 1로 주면 동작시에 메모리와 관련된 메세지들을 stderr로 뿌여준다. 2로 설정되어 있는 경우에는 바로 abort()를 호출하고 종료한다.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ MALLOC_CHECK_=&lt;font color="#ff00ff"&gt;1&lt;/font&gt; ./test&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;그외에도 사용하고 있는 memory alocation system에 대한 정보를 mallinfo()를 통해서 볼 수 있다(이 함수가 리턴하는 구조체는 return by value이다. 포인터가 아니다). 그리고 malloc_stats()를 호출하면 메모리 관련된 정보를 stderr로 뿌려주기도 한다.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-6064281814990358197?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/6064281814990358197/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/04/memory-advanced-memory-allocation.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/6064281814990358197'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/6064281814990358197'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/04/memory-advanced-memory-allocation.html' title='Memory, advanced memory allocation'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-1767673806273506032</id><published>2008-04-28T09:17:00.003+09:00</published><updated>2008-04-28T09:53:22.594+09:00</updated><title type='text'>Memory, Anonymous Memory Mappings</title><content type='html'>glibc에서 메모리를 할당할 때는 data segment나 memory mapping을 사용한다. 초기에는 2의 배수로 메모리를 쪼개 놓고 malloc호출시 요청한 size와 비슷한 free 공간을 할당해주는 식으로 동작했는데, 이 경우 실제 할당되는 메모리가 요청되 메모리보다 커서 낭비인 internal fragmentation 이 발생하고, 여러개의 작은 free memory로 쪼개져 있는 경우 공간은 있는데, 할당은 못하는 external fragmentation이 발생하는 문제가 있었다. - 이렇게 할당하던 방식을 buddy memory allocation scheme라고 불렀다(glibc는 이 알고리즘 말고도 arena algorithm이라는 더 발전된 알고리즘도 사용한다).&lt;br /&gt;&lt;br /&gt;glibc에서 메모리를 할당할 때 사용하는 heap이 free를 한다고 바로 줄어들지는 않고 할당된 메모리보다 heap이 너무 커진 경우에만 shrink 한다. 그리고 glibc는 큰 메모리 할당의 경우에는 heap을 사용하지 않는다. 일반적으로 요청된 메모리의 크기가 128 KB 이상인 경우 glibc는 anonymous memory mapping을 사용한다(mmap 과 비슷한 식으로 메모리를 커널로 부터 할당받는다). anonymous memory mapping은 아래와 같은 장단점이 있다.&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;fragmentation이 없다.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;할당 후 크기조절이 가능하다.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;heap을 거칠 필요가 없다.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;커널의 페이지 사이즈 크기 배수로 할당 받는다(공간 낭비가 있을 수 있다).&lt;/li&gt;&lt;br /&gt;&lt;li&gt;새로운 공간을 할당받는 overhead가 heap에거 가져오는 건 보다는 크다&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;anonymous memory mapping은 직접할 수도 있는데, 아래처럼 mmap을 사용하면 된다. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; *p;&lt;br /&gt;&lt;br /&gt;p = mmap(&lt;font color="#ff00ff"&gt;NULL&lt;/font&gt;,&lt;br /&gt;        &lt;font color="#ff00ff"&gt;512&lt;/font&gt;*&lt;font color="#ff00ff"&gt;1024&lt;/font&gt;, &lt;font color="#0000ff"&gt;// size&lt;/font&gt;&lt;br /&gt;        PROT_READ|PROT|WRITE, &lt;font color="#0000ff"&gt;// 권한&lt;/font&gt;&lt;br /&gt;        MAP_ANONYMOUS|MAP_PRIVATE, &lt;font color="#0000ff"&gt;// anonymous !&lt;/font&gt;&lt;br /&gt;        -&lt;font color="#ff00ff"&gt;1&lt;/font&gt;, &lt;font color="#0000ff"&gt;// fd 인데, -1안줘도 되긴 함&lt;/font&gt;&lt;br /&gt;        &lt;font color="#ff00ff"&gt;0&lt;/font&gt;); &lt;font color="#0000ff"&gt;// offset (ignored)&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#804040"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt; (p == MAP_FAILED) perror(&lt;font color="#ff00ff"&gt;&amp;quot;mmap&amp;quot;&lt;/font&gt;);&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;이렇게 할당된 메모리에서 특정 코드를 수행하려 할 수도 있겠으나, 심각한 보안 취약점이 될 수 있으므로, 하지 않는다. 할당된 메모리들은 모두 0으로 초기화 되어 있다(커널에서 이렇게 할당된 메모리들은 copy on write 로 zero filled 하기 때문에 효율적으로 0으로 초기화 된 메모리를 사용할 수 있다.)&lt;br /&gt;&lt;br /&gt;다른 unix 시스템들의 경우에는 MAP_ANONYMOUS 같은 flag이 없다. 대신에 mmap시 /dev/zero를 사용한다(이전의 linux에서도 이 방식을 사용하였다). 하지만 이 경우 추가적인 system call을 수반하기 때문에 anonymous memory가 더 빠른 방식이다.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-1767673806273506032?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/1767673806273506032/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/04/memory-anonymous-memory-mappings.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/1767673806273506032'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/1767673806273506032'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/04/memory-anonymous-memory-mappings.html' title='Memory, Anonymous Memory Mappings'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-9171903577992779848</id><published>2008-04-25T10:51:00.002+09:00</published><updated>2008-08-11T12:04:25.350+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='thread'/><title type='text'>links</title><content type='html'>&lt;strong&gt;book&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.oreilly.com/catalog/pthread/"&gt;Pthreads Programming&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;url&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="https://computing.llnl.gov/tutorials/pthreads/"&gt;https://computing.llnl.gov/tutorials/pthreads/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-9171903577992779848?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/9171903577992779848/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/04/about-thread.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/9171903577992779848'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/9171903577992779848'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/04/about-thread.html' title='links'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-3759661032630979410</id><published>2008-04-25T09:53:00.003+09:00</published><updated>2008-04-25T10:33:03.913+09:00</updated><title type='text'>Memory, Data Segment, Break Point</title><content type='html'>지금이야 heap과 stack 영역이 별도로 구분되어 있지만, 옛날에는 한 Data Segment 안에 들어있었다(학교 때 이렇게 배웠는데, 벌써 옛날이 되었네..). 그래서 스택은 제일 윗쪽 주소로 부터 내려오고, 힙은 아래서 부터 올라갔다. 두 영역이 만나는 지점을 Break 혹은 Break point 라고 하는데, 따로 구분되어 있는 지금에도 이 이름은 계속 사용된다. POSIX나 C에서 공식적으로 제공하는 것은 아니지만 brk() 함수를 통해 break point 값을 조정할 수 있고, sbrk()를 통해 현재 break point 값에서 증감할 수 있다(sbrk(0)으로 호출하면 현재 break point의 값을 알 수 있다.).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-3759661032630979410?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/3759661032630979410/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/04/memory-data-segment-break-point.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/3759661032630979410'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/3759661032630979410'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/04/memory-data-segment-break-point.html' title='Memory, Data Segment, Break Point'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-3590668279468248667</id><published>2008-04-24T23:32:00.005+09:00</published><updated>2008-04-25T09:48:53.810+09:00</updated><title type='text'>Vector Juggling Rotation</title><content type='html'>임의의 벡터를 쉬프트 시킬 때 최소한의 메모리를 사용하여 구현할 수 있는데, 이 때 각 백터 원소의 크기 x 2 의 공간만 있으면 되고 연산은 벡터의 길이에 비례하도록 할 수 있다 ( O(n) ). 저글링 연산인데, 예를들어 8개의 원소를 가지는 벡터를 왼쪽으로 2만큼 쉬프트 시키면 아래와 순서와 같다.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;1 2 3 4 5 6 7 8 - 임시공간 - 연산횟수&lt;br /&gt;&lt;br /&gt;x 2 3 4 5 6 1 8 - 7 - 1 // 1을 왼쪽으로 2만큼 이동 시키고 전에 있던 7을 보관&lt;br /&gt;&lt;br /&gt;x 2 3 4 7 6 1 8 - 5 - 2 // 7을 왼쪽으로 2만큼 이동한 공간에 놓고 5를 보관&lt;br /&gt;&lt;br /&gt;x 2 5 4 7 6 1 8 - 3 - 3 // ...&lt;br /&gt;&lt;br /&gt;3 2 5 4 7 6 1 8 - x - 4&lt;br /&gt;&lt;br /&gt;3 x 5 4 7 6 1 2 - 8 - 5&lt;br /&gt;&lt;br /&gt;3 x 5 4 7 8 1 2 - 6 - 6&lt;br /&gt;&lt;br /&gt;3 x 5 6 7 8 1 2 - 4 - 7&lt;br /&gt;&lt;br /&gt;3 4 5 6 7 8 1 2 - x - 8&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;막상 코드로 짤려니 아주 햇갈렸다 ㅡ.ㅡ;... &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;stdio.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; vector&lt;br /&gt;{&lt;br /&gt;  &lt;font color="#2e8b57"&gt;&lt;b&gt;char&lt;/b&gt;&lt;/font&gt; *data;&lt;br /&gt;  &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; size;&lt;br /&gt;};&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; * vec_init (&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; size)&lt;br /&gt;{&lt;br /&gt;  &lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; vector *pvec;&lt;br /&gt;  pvec = (&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; vector *) malloc (&lt;font color="#804040"&gt;&lt;b&gt;sizeof&lt;/b&gt;&lt;/font&gt; (&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; vector));&lt;br /&gt;  pvec-&amp;gt;data = malloc (&lt;font color="#804040"&gt;&lt;b&gt;sizeof&lt;/b&gt;&lt;/font&gt; (&lt;font color="#2e8b57"&gt;&lt;b&gt;char&lt;/b&gt;&lt;/font&gt;) * (size + &lt;font color="#ff00ff"&gt;1&lt;/font&gt;));&lt;br /&gt;  *(pvec-&amp;gt;data + size) = &lt;font color="#6a5acd"&gt;'\0'&lt;/font&gt;;&lt;br /&gt;  pvec-&amp;gt;size = size;&lt;br /&gt;  &lt;font color="#804040"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt; pvec;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; vec_free (&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; vector *pvec)&lt;br /&gt;{&lt;br /&gt;  free (pvec-&amp;gt;data);&lt;br /&gt;  free (pvec);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;// juggling rotation&lt;/font&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; vec_rotate (&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; vector *pvec, &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; shift_by)&lt;br /&gt;{&lt;br /&gt;  &lt;font color="#2e8b57"&gt;&lt;b&gt;char&lt;/b&gt;&lt;/font&gt; tmp;&lt;br /&gt;  &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; i, j, k, f, t;&lt;br /&gt;  &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; cnt = &lt;font color="#ff00ff"&gt;0&lt;/font&gt;;;&lt;br /&gt;  &lt;font color="#804040"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/font&gt; (i = &lt;font color="#ff00ff"&gt;0&lt;/font&gt;; i &amp;lt; pvec-&amp;gt;size - &lt;font color="#ff00ff"&gt;1&lt;/font&gt;; i++)&lt;br /&gt;    {&lt;br /&gt;      j = i;&lt;br /&gt;      k = (pvec-&amp;gt;size + j - shift_by) % pvec-&amp;gt;size;&lt;br /&gt;      f = *(pvec-&amp;gt;data + j);&lt;br /&gt;      &lt;font color="#804040"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;        {&lt;br /&gt;          k = (pvec-&amp;gt;size + j - shift_by) % pvec-&amp;gt;size;&lt;br /&gt;          t = *(pvec-&amp;gt;data + k);&lt;br /&gt;          *(pvec-&amp;gt;data + k) = f;&lt;br /&gt;          cnt++;&lt;br /&gt;          f = t;&lt;br /&gt;          j = k;&lt;br /&gt;        }&lt;br /&gt;      &lt;font color="#804040"&gt;&lt;b&gt;while&lt;/b&gt;&lt;/font&gt; (j != i);&lt;br /&gt;      &lt;font color="#804040"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt; (cnt &amp;gt;= pvec-&amp;gt;size)&lt;br /&gt;        &lt;font color="#804040"&gt;&lt;b&gt;break&lt;/b&gt;&lt;/font&gt;;&lt;br /&gt;    }&lt;br /&gt;  &lt;font color="#804040"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; main ()&lt;br /&gt;{&lt;br /&gt;  &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; i;&lt;br /&gt;  &lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; vector *pvec = vec_init (&lt;font color="#ff00ff"&gt;20&lt;/font&gt;);&lt;br /&gt;&lt;br /&gt;  &lt;font color="#804040"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/font&gt; (i = &lt;font color="#ff00ff"&gt;0&lt;/font&gt;; i &amp;lt; pvec-&amp;gt;size; i++)&lt;br /&gt;    *(pvec-&amp;gt;data + i) = &lt;font color="#ff00ff"&gt;'a'&lt;/font&gt; + i;&lt;br /&gt;&lt;br /&gt;  printf (&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;&lt;font color="#6a5acd"&gt;%s&lt;/font&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;, pvec-&amp;gt;data);&lt;br /&gt;  vec_rotate (pvec, &lt;font color="#ff00ff"&gt;12&lt;/font&gt;);&lt;br /&gt;  printf (&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;&lt;font color="#6a5acd"&gt;%s&lt;/font&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;, pvec-&amp;gt;data);&lt;br /&gt;  vec_free (pvec);&lt;br /&gt;&lt;br /&gt;  &lt;font color="#804040"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt; &lt;font color="#ff00ff"&gt;0&lt;/font&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;실행시키니 정상동작한다. 다행 ^^;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-3590668279468248667?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/3590668279468248667/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/04/vector-juggling-rotation.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/3590668279468248667'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/3590668279468248667'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/04/vector-juggling-rotation.html' title='Vector Juggling Rotation'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-6457720200959579873</id><published>2008-04-23T09:50:00.004+09:00</published><updated>2008-04-25T09:49:37.557+09:00</updated><title type='text'>Memory, Alignment</title><content type='html'>어떤 변수가 자신의 size의 정수배가 되는 위치에 align된 경우 naturally aligned라고 한다(예로, 32bit 정수가 4bytes 정수배의 메모리에 위치한 경우 - 이 경우 주소의 마지막 두자리가 '00'이 된다). 따라서 2^n 크기의 변수가 naturally aligned 되려면 주소의 마지막 n 비트들이 0이 된다.&lt;br /&gt;&lt;br /&gt;시스템에 따라서 alignment가 잘못되는 경우 비정상적으로 동작하거나 심각한 성능 저하를 초래할 수 있다. posix에서 alignment를 맞춰주는 함수를 제공하는데 아래와 같다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; posix_memalign (&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; **memptr, &lt;font color="#2e8b57"&gt;&lt;b&gt;size_t&lt;/b&gt;&lt;/font&gt; alignment, &lt;font color="#2e8b57"&gt;&lt;b&gt;size_t&lt;/b&gt;&lt;/font&gt; size);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;위 함수는 alignment의 정수배에 해당하는 주소에 size 만큼의 메모리를 할당한 후 그 주소를 **memptr에 담아 돌려준다.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-6457720200959579873?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/6457720200959579873/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/04/memory-alignment.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/6457720200959579873'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/6457720200959579873'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/04/memory-alignment.html' title='Memory, Alignment'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-4599158689138601784</id><published>2008-04-18T10:13:00.002+09:00</published><updated>2008-04-18T10:17:14.239+09:00</updated><title type='text'>Memory, free</title><content type='html'>free()를 사용한다. 알다시피, Linux에서 이미 할당된 메모리공간의 일부만을 free할 수는 없다(애초에 나눠서 할당하는 수밖에는). SunOS같은 경우는 cfree()같은 것을 제공하지만, linux에서는 이게 free와 같이 동작하므로(기대치 않은 동작을 발생시키는 경우가 있으니) 사용하지 않는 게 낫다.&lt;br /&gt;&lt;br /&gt;메모리 free할 때 조심해야하는 게 memory leak 이다. 이를 위해 제공되는 툴이 electric fence와 잘 알고 있는 valgrind 이다. (전자는 이름 그대로 '전기 울타리' 라서 구글링하기 상당히 불편하다 ㅡ.ㅡ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-4599158689138601784?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/4599158689138601784/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/04/memory-free.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/4599158689138601784'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/4599158689138601784'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/04/memory-free.html' title='Memory, free'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-4996575070097999504</id><published>2008-04-18T09:33:00.002+09:00</published><updated>2008-04-18T10:13:20.483+09:00</updated><title type='text'>Memory, reallocation</title><content type='html'>그렇다. realloc()으로 할당된 메모리 공간을 조절한다. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; *realloc(&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; *ptr, &lt;font color="#2e8b57"&gt;&lt;b&gt;size_t&lt;/b&gt;&lt;/font&gt; size);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;리턴되는 포인터는 원래의 것과 다를 수 있다(더 큰 메모리 공간을 연속적으로 얻기 위해 원래 위치에서 다른 위치로 옮길 수 있기 때문이다. 이 때 복사 cost가 있다). size 가 0인 경우 free와 같으나 이렇게 변태적으로 사용할 사람은 없을 거 같다.&lt;br /&gt;&lt;br /&gt;realloc()을 통해 사이즈를 더 줄일 수도 있는데, 이때 원래 ptr도 사용가능하다 (심리적으로는 이렇게 안 쓰기 마련이다.) 만약 realloc이 실패하면 원해 ptr는 유효하게 된다.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-4996575070097999504?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/4996575070097999504/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/04/memory-reallocation.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/4996575070097999504'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/4996575070097999504'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/04/memory-reallocation.html' title='Memory, reallocation'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-711744405400590962</id><published>2008-04-18T09:22:00.002+09:00</published><updated>2008-04-18T09:33:13.867+09:00</updated><title type='text'>Memory, Allocation</title><content type='html'>메모리는 잘 알다시피 malloc(size_t size)로 할당하여 사용할 수 있다. C에서는 해당 포인터에 바로 대입할 수 있지만, C++에서는 void 포인터를 자동으로 캐스팅 해주지 않으므로 아래처럼 명시적으로 케스팅 해줘야 한다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;char&lt;/b&gt;&lt;/font&gt; * name;&lt;br /&gt;&lt;br /&gt;name = (&lt;font color="#2e8b57"&gt;&lt;b&gt;char&lt;/b&gt;&lt;/font&gt; *)malloc(&lt;font color="#ff00ff"&gt;512&lt;/font&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;일부 프로그래머는 포인터를 리턴하는 함수 일부를 호출할 때 void로 변환하여(리턴값을 확인하지 않고) 쓰는데, 상당히 좋지 않은 습관이다.&lt;br /&gt;&lt;br /&gt;malloc()은 NULL을 리턴할수 있기 때문에 에러체크를 꼭해줘야한다. 그래서 일반적으로 아래 처럼 wrapper를 둬서 사용한다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; * xmalloc(&lt;font color="#2e8b57"&gt;&lt;b&gt;size_t&lt;/b&gt;&lt;/font&gt; size)&lt;br /&gt;{&lt;br /&gt;        &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; *p;&lt;br /&gt;        p = malloc(size);&lt;br /&gt;        &lt;font color="#804040"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt; (!p) perror(&lt;font color="#ff00ff"&gt;&amp;quot;xmalloc&amp;quot;&lt;/font&gt;), exit (&lt;font color="#ff00ff"&gt;EXIT_FAILURE&lt;/font&gt;);&lt;br /&gt;        &lt;font color="#804040"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt; p;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;배열을 할당할 때는 calloc()을 사용할 수 있는데, 이 함수는 값들을 0으로 초기화 해준다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; *calloc(&lt;font color="#2e8b57"&gt;&lt;b&gt;size_t&lt;/b&gt;&lt;/font&gt; nr, &lt;font color="#2e8b57"&gt;&lt;b&gt;size_t&lt;/b&gt;&lt;/font&gt; size);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;nr x size 만큼의 공간을 할당해서 0으로 초기화 한 후 포인터를 돌려준다(이미 0으로 초기화된 메모리를 돌려주기 때문에 효율적이다). 이 함수를 사용해서 아래 처럼 0으로 초기화하는 malloc의 wrapper를 따로 두기도 한다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; *xmalloc0(&lt;font color="#2e8b57"&gt;&lt;b&gt;size_t&lt;/b&gt;&lt;/font&gt; size)&lt;br /&gt;{&lt;br /&gt;        &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt; *p;&lt;br /&gt;        p = calloc(&lt;font color="#ff00ff"&gt;1&lt;/font&gt;, size); &lt;font color="#0000ff"&gt;// 1 x size&lt;/font&gt;&lt;br /&gt;        &lt;font color="#804040"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt; (!p) perror(&lt;font color="#ff00ff"&gt;&amp;quot;xmalloc0&amp;quot;&lt;/font&gt;), exit(&lt;font color="#ff00ff"&gt;EXIT_FAILURE&lt;/font&gt;);&lt;br /&gt;        &lt;font color="#804040"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt; p;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-711744405400590962?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/711744405400590962/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/04/memory-allocation.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/711744405400590962'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/711744405400590962'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/04/memory-allocation.html' title='Memory, Allocation'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-5240068281221856873</id><published>2008-04-18T09:11:00.003+09:00</published><updated>2008-04-18T09:22:30.607+09:00</updated><title type='text'>Memory, Paging and etc.</title><content type='html'>알다시피 Linux의 메모리는 페이지로 나누어져 있다(대략 4kb인데 64비트에서는 8kb이다). 실제 물리적 메모리나 하드디스크에 mapping 되어 있는 경우가 valid page이고 그외에는 fault를 일으키는 invalid page이다. 상주되지 않은 디스크를 읽으려 하는 경우 page fault가 발생하고 커널에서 해당 페이지를 하드에서 읽어 메모리로 올리는 paging in을 해준다. 반대로 메모리가 없으면 앞으로 가장 덜 사용될 것 같은 메모리의 부분을 디스크로 옮겨는 paging out을 한다.&lt;br /&gt;&lt;br /&gt;때때로 한 물리적인 공간을 여러 (virtual memory address)메모리 주소가 가지고 있는 경우가 있는데, 이때 두가지로 동작이 가능하다. 하나는 share - 말그대로 공유하게 되어 한 프로세스가 write한 내용이 다른 프로세스에 의해 보이는 경우이고, 다른 경우는 그렇게 write 동작이 일어날 때 해당 프로세스에게 독자적인 영역을 할당해주는 COW(Copy-on-write) 동작을 하는 경우이다. &lt;br /&gt;&lt;br /&gt;메모리는 여러 블럭을 묶어 memory region, segment, mapping 라고 부를 수 있는데, 각각은 아래와 같이 구분된다.&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;text segment 는 프로그램 영역이고,&lt;/li&gt;&lt;br /&gt;&lt;li&gt;stack&lt;/li&gt;&lt;br /&gt;&lt;li&gt;data segment(heap) : 동적 메모리 영역&lt;/li&gt;&lt;br /&gt;&lt;li&gt;bss segment : 초기화 안된 전역 변수공간 (이 변수들에 대해 object file에서 초기값이 없으므로 값을 저장하지 않는다. 그래서 바이너리 사이즈를 줄일 수 있다. 또 실행시에 메모리에 올라갈 때에도 copy-on-write로 동작하여 0으로 초기화 하는 작업을 효율적으로 진행한다)&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;이러한 영역들은 /proc/self/maps나 pmap을 통해 프로세스별로 어떻게 메모리가 할당되어 있는지 확인할 수 있다.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-5240068281221856873?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/5240068281221856873/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/04/memory-paging-and-etc.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/5240068281221856873'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/5240068281221856873'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/04/memory-paging-and-etc.html' title='Memory, Paging and etc.'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-6230764422244897483</id><published>2008-04-14T10:26:00.003+09:00</published><updated>2008-04-14T10:40:30.330+09:00</updated><title type='text'>Resource Limits</title><content type='html'>시스템의 리소스 제한값을 보거나 설정하는 것은 아래 함수를 통해 할 수 있다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;sys/time.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;lt;sys/resource.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; {&lt;br /&gt;        rlim_t rlim_cur; &lt;font color="#0000ff"&gt;// soft&lt;/font&gt;&lt;br /&gt;        rlim_t rlim_max; &lt;font color="#0000ff"&gt;// hard&lt;/font&gt;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; getrlimit(&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; resource, &lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; rlimit *rlim);&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; setrlimit(&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; resource, &lt;font color="#2e8b57"&gt;&lt;b&gt;const&lt;/b&gt;&lt;/font&gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; rlimit *rlim);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;리소스 제한 값에는 soft limit과 hard limit 두가지가 있는데, soft limit는 hard limit 한도내에서 자유롭게 변경할 수 있다. 각 값들은 0인 경우 disable이고, RLIM_INFINITY(-1) 인 경우 무한대이다. limit 값들의 flag 이름들은 아래와 같다.&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;RLIMIT_AS : address space 제한&lt;/li&gt;&lt;br /&gt;&lt;li&gt;RLIMIT_CORE : 코어파일 크기&lt;/li&gt;&lt;br /&gt;&lt;li&gt;RLIMIT_CPU : 최대 CPU 사용시간&lt;/li&gt;&lt;br /&gt;&lt;li&gt;RLIMIT_DATA : data segment 크기 제한&lt;/li&gt;&lt;br /&gt;&lt;li&gt;RLIMIT_FSIZE : File size&lt;/li&gt;&lt;br /&gt;&lt;li&gt;RLIMIT_LOCKS : 최대 File Lock 개수&lt;/li&gt;&lt;br /&gt;&lt;li&gt;RLIMIT_MEMLOCK : CPY_SYS_IPC 설정없이 mlock(), shmctl()등으로 가질수 있는 메모리 크기&lt;/li&gt;&lt;br /&gt;&lt;li&gt;RLIMIT_MSGQUEUE : massage queue 크기&lt;/li&gt;&lt;br /&gt;&lt;li&gt;RLIMIT_NICE&lt;/li&gt;&lt;br /&gt;&lt;li&gt;RLIMIT_NOFILE : fd갯수 제한&lt;/li&gt;&lt;br /&gt;&lt;li&gt;RLIMIT_NPROC : user가 돌릴 수 있는 process 수 제한&lt;/li&gt;&lt;br /&gt;&lt;li&gt;RLIMIT_RSS : maximun number of pages&lt;/li&gt;&lt;br /&gt;&lt;li&gt;RLIMIT_RTPRIO&lt;/li&gt;&lt;br /&gt;&lt;li&gt;RLIMIT_SIGPENDING : 최대로 queue될 수 있는 signal갯수&lt;/li&gt;&lt;br /&gt;&lt;li&gt;RLIMIT_STACK : 프로세스 스택 크기 제한&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;이러한 값들을 가지고 설정하거나, 값을 확인하는 코드 예는 아래와 같다.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt; rlimit rlim;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; ret;&lt;br /&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;// get RLIMIT_CORE value&lt;/font&gt;&lt;br /&gt;ret = getrlimit(RLIMIT_CORE, &amp;amp;rlim);&lt;br /&gt;&lt;font color="#804040"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt; (ret == -&lt;font color="#ff00ff"&gt;1&lt;/font&gt;) perror(&lt;font color="#ff00ff"&gt;&amp;quot;getrlimit&amp;quot;&lt;/font&gt;), &lt;font color="#804040"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt; &lt;font color="#ff00ff"&gt;1&lt;/font&gt;;&lt;br /&gt;&lt;br /&gt;printf (&lt;font color="#ff00ff"&gt;&amp;quot;RLIMIT_CORE sft(&lt;/font&gt;&lt;font color="#6a5acd"&gt;%ld&lt;/font&gt;&lt;font color="#ff00ff"&gt;), hrd(&lt;/font&gt;&lt;font color="#6a5acd"&gt;%ld&lt;/font&gt;&lt;font color="#ff00ff"&gt;)&lt;/font&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;, rlim.rlim_cur, rlim.rlim_max);&lt;br /&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;// set RLIMIT_CORE value&lt;/font&gt;&lt;br /&gt;rlim.rlim_cur = &lt;font color="#ff00ff"&gt;32&lt;/font&gt; * &lt;font color="#ff00ff"&gt;1024&lt;/font&gt; * &lt;font color="#ff00ff"&gt;1024&lt;/font&gt;;&lt;br /&gt;rlim.rlim_max = RLIM_INFINITY;&lt;br /&gt;ret = setrlimit(RLIMIT_CORE, &amp;amp;rlim);&lt;br /&gt;&lt;font color="#804040"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt; (ret == -&lt;font color="#ff00ff"&gt;1&lt;/font&gt;) perror(&lt;font color="#ff00ff"&gt;&amp;quot;setrlimit&amp;quot;&lt;/font&gt;), &lt;font color="#804040"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt; &lt;font color="#ff00ff"&gt;1&lt;/font&gt;;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-6230764422244897483?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/6230764422244897483/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/04/resource-limits.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/6230764422244897483'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/6230764422244897483'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/04/resource-limits.html' title='Resource Limits'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-9033833733765687872</id><published>2008-04-14T09:41:00.002+09:00</published><updated>2008-04-14T10:26:09.082+09:00</updated><title type='text'>Real-time Systems</title><content type='html'>특정 외부요인이 발현된 시점에서 응답이 있기까지의 시간에 대해 deadline이 제한된 상황에서 동작하는 시스템을 realtime system이라 할 수 있다. 책에서는 soft/hard realtime system으로 나누는데, deadline을 넘겨도 system failure가 발생하지 않는 경우는 soft realtime system 으로 보면 된다. &lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Latency &amp; Jitter&lt;/strong&gt; 두 단어에 대하 잠깐 짚고 넘어 가면, Latency는 외부요인이 발생한 시점에서부터 response가 일어나기 전까지의 시간이고, jitter는 연속적인 이벤트들 사이의 시간 편차이다. &lt;br /&gt;&lt;br /&gt;Linux에서도 realtime 을 지원하는데, scheduling class 라고 불리는 스케쥴링 정책을 통해서 이루어진다. 세가지 정책이 있는데 flag으로는 SCHED_FIFO, SCHED_RR, SCHED_OTHER로 구분된다.&lt;br /&gt;&lt;br /&gt;FIFO Class는 더 높은 우선순위를 가진 프로세스가 들어오기 전까지 FIFO순으로 처리하는 방식이고,&lt;br /&gt;&lt;br /&gt;Round-robin 은 같은 우선순위를 가진 프로세스들 간에 RR방식으로 timeslice를 가지고 실행되는 스케쥴링 방식이다. &lt;br /&gt;&lt;br /&gt;SCHED_OTHER는 일반적인 스케쥴링 정책이다. 이외에 SCHED_BATCH도 있는데, 다른말로 idle scheduling policy라고도 불린다. 이 정책은 runnable한 프로세스가 없을 때 실행되는 방식으로 realtime 과는 반대 개념으로 동작한다. 스케쥴링을 설정하거나 확인할 때는 sched_getscheduler(), sched_setscheduler()를 사용한다. RR 에서 timeslice 값을 확인하고 싶은 경우에는 sched_rr_get_interval()함수를 사용하면 된다. &lt;br /&gt;&lt;br /&gt;Real-time Process를 구현할 때 주의할 사항들이 있는데, 요약하면 아래와 같다고 한다.&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;무한 루프를 돌 경우 시스템이 응답하지 않게 될 수도 있다.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;한 프로세스로 인해 다른 프로세스가 starve하지 않도록 주의해야한다.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;자신보다 낮은 우선순위의 프로세스를 busy-wait하는 경우를 주의해야한다(deadlock될수 있음)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;개발 시에는 터미널 프로세스를 최상위에 두면 좋다.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;chrt라는 util-linux 패키지를 쓰면 도움이 된다&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;Realtime 시스템에서는 생각할 게 많다. 미사일 요격 시스템을 만들어서 잘 동작하다가, 갑자기 중요한 코드를 수행하는데 예를들어 ABM(Anti-Ballistic Missile)를 발사하려는 시점에서 갑자기 해당 코드가 하드디스크에 swap되어 있다고 가정하자. 하드에서 읽어와 메모리에 다시 올리는 순간, 이미 미사일이 나아들어 기지를 덮칠 수도 있다 ㅡ.ㅡ;... realtime 에서 동작하는 프로세스라면 해당 메모리는 swap out되지 않도록 lock해 놓을 필요가 있다.&lt;br/&gt;&lt;br /&gt;CPU Affinity를 통해서 realtime process를 설정하는 방법도 있다. multiprocessor를 가진 시스템에서 realtime process를 통작시킨다고 해보자. 이 경우에 모든 일반 프로세스를 한 프로세서에서 동작시키고 중요한 rt 프로세스를 다른 프로세서에서 동작시키면 dealine 안에 job을 마치도록 안전하게 설정 시켜 놓을 수 있다. 간단하게 init 프로세스의 CPU affinity를 한쪽으로 고정시키면 이로부터 fork되는 프로세스들도 같은 affinity를 가지므로 한쪽에서만 돈다. 그리고 원하는 RT 프로세스를 다른 CPU에서 돌도록 하면 된다. 샘플코드를 보자.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;// #### init process&lt;/font&gt;&lt;br /&gt;cpu_set_t set;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; ret;&lt;br /&gt;&lt;br /&gt;CPU_ZERO(&amp;amp;set);&lt;br /&gt;ret = sched_getaffinity(&lt;font color="#ff00ff"&gt;0&lt;/font&gt;, &lt;font color="#804040"&gt;&lt;b&gt;sizeof&lt;/b&gt;&lt;/font&gt;(cpu_set_t), &amp;amp;set);&lt;br /&gt;&lt;font color="#0000ff"&gt;//check error&lt;/font&gt;&lt;br /&gt;CPU_CLR(&lt;font color="#ff00ff"&gt;1&lt;/font&gt;, &amp;amp;set); &lt;font color="#0000ff"&gt;// cpu1에서 못돌게함&lt;/font&gt;&lt;br /&gt;ret = sched_setaffinity(&lt;font color="#ff00ff"&gt;0&lt;/font&gt;, &lt;font color="#804040"&gt;&lt;b&gt;sizeof&lt;/b&gt;&lt;/font&gt;(cpu_oset_t), &amp;amp;set);&lt;br /&gt;&lt;font color="#0000ff"&gt;// check error&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;// #### real-time process&lt;/font&gt;&lt;br /&gt;cpu_set_t set;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; ret;&lt;br /&gt;&lt;br /&gt;CPU_ZERO(&amp;amp;set)l&lt;br /&gt;CPU_SET(&lt;font color="#ff00ff"&gt;1&lt;/font&gt;, &amp;amp;set);&lt;br /&gt;ret = sched_setaffinity(&lt;font color="#ff00ff"&gt;0&lt;/font&gt;, &lt;font color="#804040"&gt;&lt;b&gt;sizeof&lt;/b&gt;&lt;/font&gt;(cpu_oset_t), &amp;amp;set);&lt;br /&gt;&lt;font color="#0000ff"&gt;// check error&lt;/font&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-9033833733765687872?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/9033833733765687872/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/04/real-time-systems.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/9033833733765687872'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/9033833733765687872'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/04/real-time-systems.html' title='Real-time Systems'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4377783716972458045.post-1726295245087565343</id><published>2008-04-08T00:14:00.002+09:00</published><updated>2008-04-08T00:24:30.846+09:00</updated><title type='text'>Processor Affinity</title><content type='html'>SMP 같이 여러 프로세서를 사용하는 경우, 프로세서를 바꿀 때 마다 cache 효과가 사라지는 단점이 있다. (오늘날의 SMP에서는 프로세서간에 Cache 접근이 가능하도록 인텔에서 설계하나, 커널 단에서 이를 고려하고 있는지는 모르겠다.) 그래서 스케쥴러는 되도록 이면 특정 프로세스를 특정 프로세서에서 동작시켜려고 하는 경향이 있는데 이를 '&lt;strong&gt;soft affinity&lt;/strong&gt;' 라고 한다. 이 경향은 프로세서가 아주 imbalance해질 때 풀어지는데, 코드 상에서 특정 프로세서에서만 실행되도록 한다면 이는 '&lt;strong&gt;hard affinity&lt;/strong&gt;' 가 된다. 몇개의 매크로와 sched_setaffinity(), sched_getaffinity()를 사용하여 hard affinity를 줄 수 있는데, 귀찮다... 소스하나만 보고 가자.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;cpu_set_t set;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; ret, i;&lt;br /&gt;&lt;br /&gt;CPU_ZERO (&amp;amp;set);&lt;br /&gt;CPU_SET (&lt;font color="#ff00ff"&gt;0&lt;/font&gt;, &amp;amp;set); &lt;font color="#0000ff"&gt;// CPU0을 선택&lt;/font&gt;&lt;br /&gt;CPU_CLR (&lt;font color="#ff00ff"&gt;1&lt;/font&gt;, &amp;amp;set); &lt;font color="#0000ff"&gt;// CPU1을 배제&lt;/font&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;// 첫째 인자는 pid&lt;/font&gt;&lt;br /&gt;ret = sched_setaffinity(&lt;font color="#ff00ff"&gt;0&lt;/font&gt;, &lt;font color="#804040"&gt;&lt;b&gt;sizeof&lt;/b&gt;&lt;/font&gt;(cpu_set_t), &amp;amp;set);&lt;br /&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;// 이제 출력해 보면,&lt;/font&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;// (CPU_SETSIZE는 한 프로세서가 최대로 &lt;/font&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;// 가질 수 있는 프로세서 수이다.)&lt;/font&gt;&lt;br /&gt;&lt;font color="#804040"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/font&gt; (i=&lt;font color="#ff00ff"&gt;0&lt;/font&gt;; i&amp;lt;CPU_SETSIZE; i++)&lt;br /&gt;{&lt;br /&gt;        &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt; cpu;&lt;br /&gt;        cpu = CPI_ISSET(i, &amp;amp;set);&lt;br /&gt;        printf (&lt;font color="#ff00ff"&gt;&amp;quot;cpu=&lt;/font&gt;&lt;font color="#6a5acd"&gt;%i&lt;/font&gt;&lt;font color="#ff00ff"&gt; is &lt;/font&gt;&lt;font color="#6a5acd"&gt;%s&lt;/font&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;, i,&lt;br /&gt;                cpu ? &lt;font color="#ff00ff"&gt;&amp;quot;set&amp;quot;&lt;/font&gt; : &lt;font color="#ff00ff"&gt;&amp;quot;unset&amp;quot;&lt;/font&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4377783716972458045-1726295245087565343?l=dustin-hyun.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dustin-hyun.blogspot.com/feeds/1726295245087565343/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dustin-hyun.blogspot.com/2008/04/processor-affinity.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/1726295245087565343'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4377783716972458045/posts/default/1726295245087565343'/><link rel='alternate' type='text/html' href='http://dustin-hyun.blogspot.com/2008/04/processor-affinity.html' title='Processor Affinity'/><author><name>Dongseok Hyun</name><uri>http://www.blogger.com/profile/17396002554548839727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://bp1.blogger.com/_HMeTW73pU4s/SCBwZra5gDI/AAAAAAAAACc/D5_0GJjAjU4/S220/dustinHyun.jpg'/></author><thr:total>0</thr:total></entry></feed>
