티스토리 뷰
======================================================
안녕하세요 Doridori 입니다.
돌아와서 환경도 많이 바뀌고 새로운 일도 알아봐야 하고 해서 힘든 11월이 지나가고 있습니다. ^^;;
12월부터는 새로운 업무에 적응 한다고 힘들어 질 것 같기는 한데 다들 힘을 주셔서 열심히 준비 하고 있습니다.
댓글이나 유튜브 구독 하나 하나로 다음 강의를 이어나갈 힘을 얻고 있습니다. ^^;;
이번 강의는 출장 나가 있을 때 댓글로 요청 해 주신 Lock에 대한 내용을 준비해 봤습니다.
그렇게 길지 않은 내용이니 쉬어가듯이 슥~ 보고 넘어가시면 좋을 것 같습니다.
언제나 화이팅 입니다. ^^
======================================================
38. Lock
Source UI) Study_38_Lock (UI).zip
Soruce 전체) Study_38_Lock.zip
교재) 38. Lock.pdf
Lock의 경우 Thread 간에 임계점을 지정하는 역할을 합니다.
Thread가 동시에 접근하지 못하게 벽을 치고 막고 있다고 생각하면 될것 같습니다.
벽으로 막고 있다가 벽이 열리면 "대기" 하고 있던 작업들을 "순차적으로" 진행 합니다.
(Lock 사용 시 대기, 순차적 진행 요것만 기억하면 될 듯 합니다.)
다른 역할이 별로 없기 때문에 어렵게 생각하지 않으셔도 될듯 하며 Lock을 사용 했을 때와 사용하지 않을 때 프로그램이 어떻게 동작 하는지만 알고 계시면 될것 같습니다.
(원래 Thread를 진행 하면서 같이 했었어야 했는데 순서가 약간 아쉽기는 합니다만 댓글로 남겨주셔서 한번 집고 넘어가게 되네요 ^^;;;)
참고로 적어 놓은 Thread 사용 할 때 인자값을 넣는 부분도 한번 집고 넘어가면 좋을 듯 합니다.
(UI)
Lock에 사용 되는 object를 바꿔 가면서 Test 할 경우 Thread가 어떤식으로 동작하는지 한눈에 볼 수 있도록 신경 써봤습니다.
Lock이 없는 경우,
각 Thread 별로 각각 Lock object를 사용 할 경우,
각 Thread 에 동일 한 Lock object를 사용 할 경우
테스트 해보시면 좋을 듯 합니다.
강의)
내용이 그렇게 길지 않아서 짧게 보시면 될듯 합니다.
그중에 반은 UI 작성하는 시간이라 UI 넘기고 보시면 빨리 보실 수 있을 것 같습니다.
개념만 잡고 넘어가면 Thread 사이에 Lock만 넣어 놓은 부분이라서 이해및 사용이 어렵진 않을 듯 합니다.
Source)
강의에 넣으려고하다가 깜빡한 부분인데 만약 Lock 위에 소스를 적용 시켜 놓으면 Lock 위의 부분은 Lock이 없는 것과 동일 하게 동작 하고 Lock 부분에서 대기 하고 있습니다. (테스트 해보시면 좋을 듯 합니다.)
(줄번호가 돌아왔습니다. ^^;;)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace LockEx { public partial class Form1 : Form { Thread _T1; // Thread Thread _T2; // Thread object RoomLock = new object(); // Lock에 사용 할 object object RoomLock2 = new object(); // Lock에 사용 할 object (Test 용) int _iRoom1Count = 1; int _iRoom2Count = 1; public Form1() { InitializeComponent(); } /// <summary> /// btnRoom1 Click Event /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnRoom1_Click(object sender, EventArgs e) { lboxRoom1.Items.Add(string.Format("Room 1 : {0} 예약", _iRoom1Count)); // ListBox의 Item에 값을 넣어 줌 (Thread 내부에서 UI에 접근하지 않음으로 바로 등록 가능) _T1 = new Thread(new ParameterizedThreadStart(Run)); // Thread 함수에 Parameter를 전달 하기 위해 사용 (함수는 object로 선언 해야 함) _T1.Start(_iRoom1Count); // Thread 시작 시 Parameter 전달 _iRoom1Count++; } /// <summary> /// Thread에 사용 할 함수 (인자값은 object type으로 정의해야 함) /// </summary> /// <param name="obj"></param> private void Run(object obj) { lock (RoomLock) // Lock (Thread 임계지점 등록) { // 참고 : Thread 내에서 UI Update가 필요 할 경우 Update 시점에만 UI 쪽으로 접근 권한을 넘겨 줘서 사용 하는것이 좋음 // 아닐 경우 Thread가 수행 중일 경우 UI가 Thread를 점유 하는 경우가 밥생 (프로그램이 버벅댐) invokeFunction(lblLockStatus, String.Format("Room 1 : Player {0} 사용 중", obj)); // Thread 내 UI Update를 위한 별도 함수 지정 (자주 사용 되어 별도 지정) for (int i = 1; i <= 3; i++) { if (InvokeRequired) { Invoke(new Action(delegate () { lboxResult.Items.Add(String.Format("Room 1 : Player {0} 진행 중 . . . {1}", obj, i)); Refresh(); })); } Thread.Sleep(1000); // Program 강제 Delay를 주기 위해 Thread를 1초간 멈춰 놓음 } invokeFunction(lblLockStatus, String.Format("Room 1 : Player {0} 사용 완료", obj)); Thread.Sleep(1000); } } private void btnRoom2_Click(object sender, EventArgs e) { lboxRoom2.Items.Add(string.Format("Room 2 : {0} 예약", _iRoom2Count)); _T2 = new Thread(new ParameterizedThreadStart(Run2)); _T2.Start(_iRoom2Count); _iRoom2Count++; } private void Run2(object obj) { //lock (RoomLock2) // 개별 Lock을 사용 했을 떄 동작 확인 용 (Test 용) lock (RoomLock) { invokeFunction(lblLockStatus, String.Format("Room 2 : Player {0} 사용 중", obj)); for (int i = 1; i <= 3; i++) { if (InvokeRequired) { Invoke(new Action(delegate () { lboxResult.Items.Add(String.Format("Room 2 : Player {0} 진행 중 . . . {1}", obj, i)); Refresh(); })); } Thread.Sleep(1000); } invokeFunction(lblLockStatus, String.Format("Room 2 : Player {0} 사용 완료", obj)); Thread.Sleep(1000); } } /// <summary> /// Label에 대해서 다른 Thread에서 수행 시 UI Update를 시켜 주기 위한 함수 /// </summary> /// <param name="objlabel"></param> /// <param name="str"></param> private void invokeFunction(Label objlabel, string str) { if (InvokeRequired) { Invoke(new Action(delegate () { objlabel.Text = str; })); } } } } | cs |
'C# > C# 강좌 Winform' 카테고리의 다른 글
Doridori C# 강의 2) 40. User32.dll (2) (Copy&Paste) (6) | 2020.02.09 |
---|---|
Doridori C# 강의 2) 39. User32.dll (Keyboard Hook) (4) | 2020.01.27 |
Doridori C# 강의 2) 37. 재귀 함수 (Recursion Function) (6) | 2019.11.14 |
Doridori C# 강의 2) 36. LinkedList, SortedList (18) | 2019.05.05 |
Doridori C# 강의 2) 35. Coding 및 Code 정리 (Program 만들기) (12) | 2019.04.26 |
- Total
- Today
- Yesterday
- 술
- 도리도리
- 칵테일
- 모바일
- 아이랑
- 가볼만한곳
- 도리도리 C#
- 게임
- 막걸리
- 광저우
- C# 강좌
- 증류주
- 서울
- 나들이
- 보드카
- 맥주
- 와인
- 하이볼
- 소주
- 위스키
- C# 기초 강의
- 맛집
- 프로그램 강의
- C# 강의
- Visual Studio
- C#
- 전통주
- 가볼만한 곳
- WinForm
- 주말
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |