Chương  3.  Kiểm  soát  xung  đột   Synchronization  Technique   Lương  Ánh  Hoàng   hoangla@soict.hut.edu.vn

Nội  dung

3.1  Khái  niệm   3.2  Đoạn  găng  (Critical  Section).   3.3  Đèn  hiệu  (Semaphore)     3.4  Mutex   3.5  Event   3.6  SRW  Lock

47

3.1  Khái  niệm

§  Xung  đột  là  vấn  đề  phát  sinh  khi  nhiều  luồng  của  chương  trình  chạy   trên  bộ  vi  xử  lý  đa  nhân  cùng  truy  nhập  một  tài  nguyên  hệ  thống.

§  Ví  dụ

WINAPI  Thread(LPVOID    lpParam)

int  x  =  0;   DWORD {

for  (int  i=0;i<2000000;i++)  x++;    return  0;

}   int  _tmain(int  argc,  _TCHAR*  argv[])   {

HANDLE  hThread1  =  CreateThread(NULL,NULL,Thread,NULL,NULL,NULL);    HANDLE  hThread2  =  CreateThread(NULL,NULL,Thread,NULL,NULL,NULL);    WaitForSingleObject(hThread1,INFINITE);    WaitForSingleObject(hThread2,INFINITE);    printf("X=%d",x);    getch();    return  0;

}

48

3.2  Đoạn  găng

§  Đoạn  găng  (Critical  Section)  là  đoạn  chương  trình  được  bảo  vệ  bởi  hệ   điều  hành  sao  cho  tại  mọi  thời  điểm  chỉ  có  một  luồng  được  phép  thực   thi.

§  Sử  dụng

CRITICAL_SECTION  cs    InitializeCriticalSection(&cs)

§  Khai  báo:   §  Khởi  tạo:   §  Sử  dụng

§  Ví  dụ   §  Đặc  điểm:  chỉ  có  tác  dụng  trong  cùng  một  tiến  trình

EnterCriticalSection(&cs)    //  Bắt  đầu  đoạn  găng    …    //  Kết  thúc  đoạn  găng    LeaveCriticalSection(&cs)    //      DeleteCriticalSection(&cs)

49

3.3  Đèn  hiệu   §  Đèn  hiệu  (Semaphore)  dùng  để  giới  hạn  số  lượng  luồng  tối  đa  được

phép  thực  thi  cùng  một  đoạn  chương  trình.

§  Sử  dụng

HANDLE  hSemaphore    hSemaphore  =  CreateSemaphore(NULL,5,5,NULL)

§  Khai  báo:   §  Khởi  tạo:   §  Sử  dụng

§  Ví  dụ   §  Đặc  điểm

WaitForSingleObject(hSemaphore,  0L)    //    …    //    ReleaseSemaphore(hSemaphore,1,NULL)    //    CloseHandle(hSemaphore)

§  Dùng  chung  được  giữa  các  tiến  trình   §  Tốc  độ  chậm  hơn  CRITICAL_SECTION

50

3.4  Mutex

§  Mutex  dùng  để  bảo  vệ  tài  nguyên  của  chương  trình,  tại  một  thời  điểm

chỉ  cho  phép  một  luồng  của  một  tiến  trình  truy  nhập.

§  Sử  dụng

HANDLE  hMutex;    hMutex  =  CreateMutex(NULL,  FALSE,  NULL)

§  Khai  báo:   §  Khởi  tạo:   §  Sử  dụng

§  Ví  dụ   §  Đặc  điểm

WaitForSingleObject(hMutex,  INFINITE)    //    …    //    ReleaseMutex(hMutex)

§  Chậm  hơn  CRITICAL_SECTION   §  Có  thể  đồng  bộ  giữa  các  tiến  trình

51

3.5  Event

§  Event  dùng  đồng  bộ  hoạt  động  của  các  luồng  thông  qua  cơ  chế  báo

hiệu.   §  Sử  dụng

HANDLE  hEvent;    hMutex  =  CreateEvent(NULL,  TRUE,  FALSE,  “MyEvent”)

§  Khai  báo:   §  Khởi  tạo:   §  Sử  dụng

//  Báo  hiệu  các  luồng  khác    //  Chặn  các  luồng  khác

§  Ví  dụ

WaitForSingleObject(hEvent,  INFINITE)    //    …    SetEvent(hEvent)    ResetEvent(hEvent)  …    //    CloseHandle(hEvent)

52

3.5  SRW  Lock

§  SRW  Lock  (Slim  Reader  Writer  Lock  )dùng  đồng  bộ  hoạt  động  của  các

luồng  thông  tương  tự  như  đoạn  găng

§  Sử  dụng

lock;    SRWLOCK    InitializeSRWLock(&lock);

§  Khai  báo:   §  Khởi  tạo:   §  Sử  dụng

§  Ví  dụ

AcquireSRWLockShared(&lock)    AcquireSRWLockExclusive(&lock)    //    …    //    ReleaseSRWLockShared(&lock)    ReleaseSRWLockExclusive(&lock)

53

Bài  tập

1.  Viết  chương  trình  chat  Client  và  Server  với  kênh  truyền  đã  mã   hóa    bằng  thuật  toán  AES-­‐256,  sử  dụng  thư  viện  OpenSSL  và   CryptoAPI.  Mật  khẩu  mã  hóa  là  :  123456.  Việc  mã  hóa  và  việc   nhận  dữ  liệu  được  thực  hiện  đồng  thời  trên  2  luồng  riêng  biệt,  sử   dụng  cơ  chế  đồng  bộ  CRITICAL_SECTION

2.  Viết  chương  trình  mã  hóa  và  giải  mã  tệp  tin  theo  thuật  toán

AES-­‐256,  với  tên  nhập  từ  bàn  phím,  mật  khẩu  mã  hóa  là  :nopass.   Sử  dụng  thư  viện  OpenSSL  và  CryptoAPI

54