'분류 전체보기'에 해당되는 글 159건

  1. 2008.12.10 API 이용 정보 #1
  2. 2008.12.04 오라클 프로세스 설정
  3. 2008.12.03 TreeView Sample
  4. 2008.11.14 Thread #1
  5. 2008.11.14 Thread #2_1
  6. 2008.11.14 Thread #2
  7. 2008.11.14 Thread #3
  8. 2008.11.14 Threading
  9. 2008.11.14 Button 테두리 변경
  10. 2008.10.30 JEUS 4.2설정

Pinvoke 라는 기법을 사용하시면 됩니다.

 

Pinvoke 는 닷넷에서 자체적으로 제공되지 않는 외부 함수를 호출하는 방법입니다.

 

관리 코드가 아닌 비 관리 코드를 사용하는 방법이라 보시면 되겠습니다.  api 호출 등이 Pinvoke 죠.

 

닷넷에서 시스템 관련 작업이나  윈도용 어플리케이션을 개발하다보면 부득이하게 Pinvoke 기법을 쓸 수 밖에 없죠.

 

특히  c 를 하다 넘어가면  api 때문에 빈번하게 Pinvoke 를 활용하는데 그에 해당하는 문서 중에선 정리가 잘된

 

있어서 퍼 옵니다.

 

"c계열이 최고다"는 아니지만 c# 이나 asp.net 부터 프로그래밍을 배운 분들이더라도 앞으로 윈도 프로그래밍을

 

하실거면 각종 API 관련 공부를 해두시는게 개발하는데 큰 도움이 됩니다.

 

닷넷 프레임웍이 버젼업하면서 라이브러리에서 제공되는 클래스&메소드가 늘어가긴 한다지만 제공 하기 전까진

 

Pinvoke 활용도가 높을겁니다. 

 

더 상세 정보는 http://www.pinvoke.net/ 여기로..

 

---------------------------------------------------------------------------

 

 

Posted by penguindori
카테고리 없음2008. 12. 4. 11:24
 

1. oracle의 현재 설정된 processes 를 확인한다.

 

SQL> show parameter processes

NAME                                 TYPE                  VALUE
--------------------------------------------------------

aq_tm_processes                      integer             1
db_writer_processes                  integer            1
job_queue_processes                  integer         10
log_archive_max_processes            integer        2
processes                            integer             150
SQL>

 

2. alter system set 명령으로 spfile 을 수정합니다.

주의) 이 명령으로 동적으로 DB에 반영되지는 않습니다. DB를 다시 오픈 시켰을때 반영됩니다.

 

SQL> alter system set processes=200 scope=spfile ;

System altered.

SQL>

 

3.spfile 에서 process수가 200 으로 바뀐지를 확인합니다.

  참조)굳이 확인할 필요는 없으며 spfile은 binary 파일이므로 vi로 편집이 불가능 합니다.

 

[oracle@angka dbs]$ pwd
/oracle/app/oracle/product/9.2.0/dbs
[oracle@angka dbs]$ more spfileORA92.ora


.....

.....
*.job_queue_processes=10
*.large_pool_size=16777216
*.open_cursors=300
*.pga_aggregate_target=33554432
*.processes=200
*.query_rewrite_enabled='TRUE'
*.remote_login_passwordfile='EXCLUSIVE'
*.shared_pool_size=83886080
*.sort_area_size=1048576
.....

.....

 

4. DB를 shutdown 시킵니다.

SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL>

 

5. DB를 다시 올리고 process수가 200으로 바뀐지를 확인합니다.

SQL> startup
ORACLE instance started.

Total System Global Area  219223120 bytes
Fixed Size                   451664 bytes
Variable Size             201326592 bytes
Database Buffers           16777216 bytes
Redo Buffers                 667648 bytes
Database mounted.
Database opened.

 

SQL> show parameter processes

NAME                                 TYPE                  VALUE
--------------------------------------------------------

aq_tm_processes                      integer             1
db_writer_processes                  integer            1
job_queue_processes                  integer         10
log_archive_max_processes            integer        2
processes                            integer             200
SQL>

 

참고) pfile 로 DB를 오픈해서 쓰고 있는 시스템에서는 initORA.ora 파일의 processes를 직접수정하고 DB를 다시 올리시면 됩니다.


Posted by penguindori
카테고리 없음2008. 12. 3. 16:56
Posted by penguindori

.NET 에서Threading 라는 단어를 떠올리면 좀 막막하다거나 혹은 어디다 써먹지 하는 생각이 떠오릅니다. 그렇지만 이것 역시 개발시 거르지 않고 항상 사용하게 되는 핵심 기반 기술입니다.

Multi-Threading 이라고 하면 예전에는 서버 시스템을 구축할 때나 힘겹게 사용하던 개발 기술입니다만 요즘은 개인PC에도 하이퍼스레딩이나 다중 프로세서가 일반화된 상황이다보니 MultiThread는 뛰어난 성능의 프로그램을 만들고자하는 개발자에게는 필수 지식이 되었습니다.

Thread가 뭔가 하는 물음에 대해서는 아래 설명 및 예제들을 통해서 자연스럽게 받아들일 수 있다면 좋겠습니다.

 Thread 생성

    - 별도의 Thread로 실행시킬 Method 생성( DoSomething )

    - ThreadStart delegate(대리자) 정의

       : Thread의 Start 메소드 호출 시 실행될 메소드(DoSomething)를 등록합니다.

    - Thread 개체 생성

       : 앞서 생성한 ThreadStart delegate 개체를 생성자 파라메터로 줍니다.

    - 앞단계에서 생성한 Thread개체의 Start 메소드 호출

       : DoSomething 메소드는 이제 Main이 실행중인 Thread와 다른 새로운 Thread에서 실행되게

         됩니다.

아래 코드예를 참고하세요.

 

Multiple Threads

이번에는 DoSomething 메소드를 여러개의 다른 Thread로 실행하도록 해보겠습니다. 앞의 예제보다는 이것이 더 현실적일 거 같습니다. MultiThread로 실행시킬 일이 없다면 굳이 별도의 Thread로 실행시킬 이유도 없겠죠.

아래는 결과 화면입니다. DoSomething이 10개의 별도 Thread로 실행되었습니다.

위 결과만을 보면 너무 빨리 끝나 버리기도 하고 해서 기능적으로만 보면 단순히 DoSomething을 10번 호출하는 거랑 크게 다르지 않아 보입니다. 그래서 이번에는 효과를 시각적으로 확인할 수 있도록 DoSomething 메소드를 아래와 같이 코드를 수정했습니다.

현재 자신이 실행중인 Thread의 ManagedThreadID를 한번만 출력하던 것을 10번 출력하게 수정했습니다.  매 출력시마다 1/100초동안 멈추었다 다시 실행하도록(Sleep(10)) 했습니다. 생성된 10개의 Thread가 동시에 실행중이라고 한다면 ThreadID 값이 뒤죽박죽 섞여서 출력이 될 것입니다. 그렇지 않다면 각 ThreadID가 동일한 값이 10번씩 출력되겠죠.

아래는 결과 화면입니다.

 

Join

위 코드에 아래와 같이 Console.WriteLine ... 을 추가했습니다. "실행완료?" 라는 문자열이 어느시점에서 뿌려질까요. 아래는 코드 및 결과입니다.

Multi-Threading의 당연한 결과지만 앞서 실행시킨 10개의 Thread가 완료되기 전에 Console.WriteLine..이 실행됐습니다. 그렇지만 현재 Thread가 실행을 완료할 때까지 기다려야 하는 상황이 자주 있습니다. 이럴 경우 사용하는 것이 Thread의 Join 메소드입니다. 아래 코드 예제와 결과를 보세요.

생성된 Thread을 별도로 저장했다가 Console.WriteLine을 호출하기 전에 Join 했습니다. 이는 별도로 실행되던 각 Thread들을 Main의 Thread에 연결함으로써 내가 종료될 때까지 기다려 달라고 말하는 것입니다.

 

ThreadPriority - Thread 실행 우선 순위

Thread들의 실행은 CPU 기능이나 갯수에 따라 다르겠지만 일정한 순서없이 이루어 집니다. 그러나 특정 Thread의 실행순서를 제어해야 하는 상황이 있을 수 있습니다. 이럴 때 사용하는 것이 ThreadPriority 입니다. ThreadPriority 값은 아래와 같습니다.

===================================================================

Highest, AboveNormal, Normal(기본값), BelowNormal, Lowest

===================================================================

우선순위는 신중하게 다루는 것이 좋습니다. 사실 우선순위라는 것 자체가 Multi-Thread의 기본 정신(CPU 자원을 최대한 활용할 수 있도록 동시에 여러 작업을 수행시킨다는)에 위배되는 내용이죠. 특히 주의해야될 상황이 있습니다. 특정 스레드에 우선 순위를 너무 높게 설정할 경우 다른 스레드를 굶겨(CPU시간상)죽이는 경우가 있을 수 있고 물론 그 반대의 상황이 발생할 수도 있습니다.

 

Thread의 중단 & ThreadAbortException

 

 

Execution Context

[출처] Threading - (1) 기초|작성자 유후


Posted by penguindori

동시에 실행되는 여러개의 Thread가 동시에 같은 변수(예에서 Count)를 수정할 경우 문제가 발생할 수 있습니다.

아래 그림을 보세요.

 

두 Thread가 연산을 했으니까 당연히 Count는 12가 되어야 하지만 결과는 11입니다.

이와 같은 Thread간의 데이터 공유 문제를 해결하기 위해서 .NET Framework은 상황에 맞는 다양한 해결책을 제시하고 있습니다.

 

Interlocked Class

증가(1증가), 감소(1 감소)와 같은 증감 연산시에 사용합니다. 위의 코드를 Interlocked 클래스를 사용하도록 변경하면 아래와 같습니다.

    static void UpdateCount()

    {

        for(int i=0;i<10000;i++)

        {

            Interlocked.Increment(ref count);

        }

    }

 

Interlocked.Increment(count); 이 코드가 특정 Thread에 의해 실행되는 동안 다른 Thread는  count 변수에 접근할 수 없습니다.

아래는 Interlocked Class가 제공하는 static method 목록입니다.

 Add  두 값을 더한다.
 Decrement  1을 뺀다.
 Exchange  두 값을 바꾼다.
 Increment  1을 더한다.
 Read  64비트 수를 읽는다.

 

Synchronization Locks

Interlocked 클래스를 사용하면 특정 값에 대한 단위실행(atomic operation)을 보장할 수 있습니다만 더 큰 단위인 object에 대한 처리라면 어떻게 될까요. 보통 object는 여러개의 값을 멤버로 가지게 되고 이에 대해 연산이 수행됩니다. 물론 이것도 object내에서 특정 변수 연산에 Interlocked 클래스를 사용하면 되지 않겠냐고 생각할 수도 있겠지만 단순하지 않습니다.

아래 예제를 보세요.

Counter 클래스를 별도로 만들었습니다. 전체 갯수(count) 및 count가 짝수일 경우 1 증가되는 evenCount가 있습니다. UpdateCount 메소드 내에서 이들 값에 대한 조작시 Interlocked를 사용했기때문에 이들 값이 CPU의 레지스터에 올라가 있는 동안 다른  Thread가 접근 못할 것이고 결과는 우리가 원하는 count=10만, evenCount=5만이 될 것입니다....라고 상상해볼 수 있습니다만 살펴보면 문제가 있습니다.

Interlocked.Increment(ref count)는 문제없습니다. 실행결과는 항상 10만으로 정확합니다. 그러나 evenCount가 계산되는 과정을 보세요.

어느정도 진행되어 count 값이 현재 9(홀수) 라고 가정합니다.

1. Thread1 이 Interlocked.Increment(ref count)를 실행하여 count=10 이 된다.

2. 1이 완료되고 Thread1이 Interlocked.Increment(ref evenCount)을 실행하기전에 Thread2 가 Interlocked.Increment(ref count)을 실행되어 count=11 이 된다.

3. Thread1이 Interlocked.Increment(ref evenCount)을 실행하려고 보니가 count값이 11이어서 evenCount에 대한 1증가 연산이 이루어지지 않는다.

이 상황이라면 10일때 evenCount가 1증가 이뤄져야하는 상황이 사라져 버리는 결과가 오게됩니다. 이와 같은 문제를 해결하기 위해 Synchronization lock이라는 기능을 제공합니다.

Synchronization lock 을 이용하면 UpdateCount를 아래와 같이 수정할 수 있습니다.

위처럼 특정 코드 영역을 lock 키워드를 사용해서 묶습니다. 이는 이 코드 영역이 특정 Thread에 의해 실행되는 동안 다른 Thread는 이 코드 영역을 실행할 수 없도록 합니다.

 

Monitor

Synchronization lock의 이면에는 실제로 Monitor 클래스가 작동을 합니다.  아래는 Monitor 클래스의 주요 static 메쏘드입니다.

 Enter  명시한 object에 lock을 건다.
 Exit  명시한 object에 걸린 lock을 해제한다.
 TryEnter  Enter와 같지만 lock을 얻기까지의 최대 시간(timeout)을 지정한다.
 Wait  lock을 해제하지만 다시 그 lock을 얻을때까지 현재 Thread를 중단한다.
   

Monitor 클래스를 이용해서 앞의 Counter 클래스를 변경하면 아래와 같습니다.

 

Deadlock

데드락은 두 쓰레드가 동일 자료에 대해서 lock을 동시에 요청함으로서 lock을 얻지 못하고 무한 대기상태에 빠지는 것을 말합니다.

위 코드에서 데드락이 발생하는 절차는 아래와 같습니다.

1. threadA가 먼저 실행되어 MethodA 코드에 따라 data1에 lock을 건다.

2. threadB가 실행되어 MethodB 코드에 따라 data2에 lock을 건다.

3. threadA가 threadB가 잡고 있는 data2에 대한 lock이 풀릴때까지 대기한다.

4. threadB는 threadA가 잡고 있는 data1에 대한 lock이 풀릴때까지 대기한다.

5. 무한대기 상태로 돌입한다.

 

이러한 데드락에 대한 해결책은 따로 없습니다. 개발자가 신중하게 개발해야 한다는 것 외에는..

조언이 될만한 것이라면 Monitor.TryEnter를 사용해서 타임아웃을 지정하거나 하는 정도일 것입니다. 가능하면 lock 거는 범위를 최소화 하는 것도 좋을 것입니다.

 

다음에는 Mutex, Semaphore, AutoResetEvent, ManualResetEvent 에 대해서 추가로 알아볼 생각입니다.

Posted by penguindori

Multi-Thread(이하 MT) 응용프로그램을 개발한다는 것은 컴퓨터 자원을 최대한 활용하여 성능을 높인다는 면에서 좋은 일이지만 개발자가 절대 간과해서 안되는 것이 하나 있습니다. 바로 MT간의 데이터 공유 문제입니다. 간단히 생각해 봐도 문제가 생길 여지가 많음을 쉽게 떠올릴 수 있습니다. 예를 들어 10개 정도의 Thread가 동시에 하나의 공유(전역으로 선언된 static 같은...) 변수를 조작한다고 할 때 그 값의 변화들이 개발자가 예상하는 대로 나와줄까요.

 아래 코드예를 보세요.

 

아래는 실행결과입니다.

 

위의 코드에서 count 값을 1 증가시키는 연산명령이 컴퓨터상에서 물리적으로 처리되는 과정을 나열해 보면 아래와 같습니다.

    1. 메모리에 있는 count의 현재값을 프로세서의 레지스터(register)로 읽어들인다.

    2. 레지스터에 읽어들인 그 값을 1만큼 증가시킨다.

    3. 레지스터에서 변경된 그 값을 메모리로 복사한다.

위 처리 절차 자체로는 아무 문제가 없습니다. 원래 CPU 역할이 그거니까. 문제는 프로세서가 여러개인 경우 또는 Hyper Threading(하나지만 CPU가 여러개인 것처럼 연산을 동시에 할 수 있는)을 지원하는 CPU인 경우에는 MT하에서는 아래와 같은 문제가 발생할 수 있습니다.

Posted by penguindori

ReaderWriterLock

읽을 때는 여러 쓰레드가 동시에 읽을 수 있고 쓰기를 할 때만 배타적 잠금을 할 수 있도록 해주는 것이 ReaderWriterLock 클래스입니다.

ReaderLock이 걸린 상황에서는 다른 쓰레드도 같은 자원에 접근해서 읽을 수 있습니다. WriterLock이 걸리면 다른 쓰레드는 접근할 수 없습니다. 단 WriterLock을 얻기 위해서는 현재 걸려있는 모든 ReaderLock이 해제되어야 합니다.

ReaderWriterLock 클래스 Method 입니다.

 IsReaderLockHeld  ReaderLock 걸려있는지 여부
 IsWriterLockHeld  WriterLock 걸려있는지 여부
 AcquireReaderLock  지정 시간내에 ReadLock을 건다. 시간초과시 응용프로그램 오류.
 AcquireWriterLock  지정 시간내에 WriterLock을 건다. 시간초과시 응용프로그램 오류.
 DowngradFromWriterLock  WriterLock을 ReaderLock으로 변경
 ReleaseReaderLock  ReaderLock 해제
 ReleaseWriterLock  WriterLock 해제
 UpgradeToWriterLock  ReaderLock을 WriterLock으로 변경

 

[예제]

참고로 Downgrade/Upgrade시에는 이전 Lock 수준으로 복귀할 때 필요한 정보로 LockCookie를 사용합니다.

 

지금까지의 synchronization lock은 thread간의 데이터공유에 한정하여 사용된 것들입니다. 운영체제의 커널(kernel)에서 제공되는 object인 Mutex, Semaphore, Event(AutoResetEvent, MaunalResetEvent) 등은 AppDomain 및 Process 경계를 넘어 데이터를 공유하고 lock을 걸 수 있는  기능을 제공합니다. 이들의 공통점은 WaitHandle을 Base 클래스로 하고 있다는 것입니다. WaitHandle은 Win32 동기화 핸들을 캡슐화한 클래스로 현재 특정 공유자원에 대해 배타적 접근(lock)을 하고 있는 쓰레드간에 신호를 주고 받을 수 있도록 하여 공유자원에 대한 배타적 접근(lock)을 원하는 오브젝트들이 제대로 작동할 수 있도록 해주는 메카니즘을 제공합니다.

 

Mutex

 

Semaphore

 

Event

AutoResetEvent

ManualResetEvent

 

Posted by penguindori
Posted by penguindori
Common C#/C# GDI+ Study2008. 11. 14. 10:12
http://www.microsoft.com/korea/msdn/smartclient/community/wffaq/ctrl.aspx#Qca22q9ci
using System.Drawing;
using System.Windows.Forms;

public class ButtonWithCustomBorder : Button
{
  protected override void OnPaint( PaintEventArgs e )
  {
    base.OnPaint( e );
    
    Color borderColor = Color.Blue;
    int borderWidth = 1; 
    int borderStyle = ButtonBorderStyle.Solid;

    ControlPaint.DrawBorder(
      e.Graphics, e.ClipRectangle,
      borderColor, borderWidth, borderStyle,
      borderColor, borderWidth, borderStyle,
      borderColor, borderWidth, borderStyle, 
      borderColor, borderWidth, borderStyle ); 
  }
}

Posted by penguindori
2008/Spring 2.52008. 10. 30. 11:04
Posted by penguindori