학교
[컴퓨터 네트워크] Socket programming (Part 2) - (3)
일자 : 24-2 11주차 2차시
[9] 동기화
동기화 문제
두 개 이상의 스레드가 공유 데이터를 접근할 때, 오직 하나의 스레드만이 공유 데이터를 접근할 수 있으며, 다른 스레드는 접근할 수 없어야 한다.
일반적인 동기화 방법
뮤텍스(Mutex)
세마포어(Semaphore)
[10] 동기화 문제
1) 정상

변수
num에 순차적으로 접근하면 문제가 발생하지 않는다.상황 설명
변수 num에 순차적으로 접근할 때는 문제가 발생하지 않는다.
Thread 1이 num을 99에서 100으로 증가시키고
Thread 2가 그 후에 100에서 101로 증가시킨다.
결과적으로 변수가 예상대로 2번 증가하여 101이 된다.
2) 비정상

동기화 문제
스레드 1과 스레드 2는 각각 1씩 증가하지만, 변수
num은 1만 증가한다.상황 설명
두 스레드가 동시에 변수에 접근할 때 발생하는 문제를 보여준다.
Thread 1과 Thread 2가 각각 변수를 1씩 증가시키려고ㅎ한다.
하지만 두 스레드가 거의 동시에 변수 num에 접근하면서:
Thread 1이 99를 읽음
Thread 2도 99를 읽음
Thread 1이 100으로 증가
Thread 2도 100으로 증가
결과적으로 두 번의 증가 연산이 있었음에도 변수는 단 한 번만 증가한 것처럼 된다.
이는 Race Condition이라고 불리는 전형적인 동기화 문제이다
이러한 문제를 해결하기 위해서는 뮤텍스(Mutex)나 세마포어(Semaphore)와 같은 동기화 메커니즘을 사용해야 한다.
이를 통해 한 번에 하나의 스레드만 변수에 접근할 수 있도록 보장할 수 있습니다.
[11] 뮤텍스 (Mutex)
뮤텍스 변수는 공유 데이터 자원에 대한 접근을 보호하는 "잠금"처럼 작용한다.
한 번에 하나의 스레드만 뮤텍스 변수를 잠글(또는 소유할) 수 있다. 따라서 여러 스레드가 뮤텍스를 잠그려고 시도하더라도 오직 하나의 스레드만 성공하게 된다.
다른 스레드는 소유 스레드가 해당 뮤텍스를 잠금 해제할 때까지 그 뮤텍스를 소유할 수 없다. 스레드는 보호된 데이터에 접근하기 위해 "차례대로" 접근해야 한다.
[12] 뮤텍스 함수들
#include <pthread.h>
int pthread_mutex_init(pthread_mutex_t *restrict mutex,
const pthread_mutexattr_t *restrict attr);
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
int pthread_mutex_destroy(pthread_mutex_t *mutex);뮤텍스 변수(
mutex)는 사용되기 전에pthread_mutex_init()을 통해 초기화되어야 한다.
1) 파라미터 설명
mutex: 뮤텍스 변수attr: 기본값은 NULL
2) 설명
pthread_mutex_lock()함수는 스레드가 지정된 뮤텍스 변수에 대한 잠금을 획득할 때 사용된다. 만약 뮤텍스가 이미 다른 스레드에 의해 잠겨 있으면, 해당 스레드는 잠금이 풀릴 때까지 대기한다.pthread_mutex_unlock()함수는 소유 스레드가 호출할 경우 뮤텍스 잠금을 해제한다.
4. 간단한 웹 서버 구현
[1] 간단한 웹 서버

TCP 소켓을 사용하여 간단한 웹 서버를 구현한다.
우리 웹 서버는 클라이언트 요청에 의해 간단한 웹 페이지를 제공할 수 있다.
동시성을 지원하는 서버를 구현할 것이다.
클라이언트 프로그램을 구현하는 대신 웹 브라우저를 사용할 것이다.
[2] 간단한 웹 서버를 위한 함수 호출
1) 서버 측 초기화 단계:
socket() - 서버 소켓 생성
bind() - 소켓을 특정 IP와 포트에 바인딩
listen() - 클라이언트의 연결 요청을 대기
2) 통신 과정:
클라이언트 측:
웹 브라우저 실행
URL 입력하여 서버에 연결 요청
연결 설정:
클라이언트가 연결 요청 (Connection Request) 보냄
서버의 accept() 함수가 이를 수락
새로운 스레드 생성하여 클라이언트 요청 처리
HTTP 통신:
클라이언트: HTTP Request 전송 (예: "GET /index.html HTTP/1.1")
서버: request_handler()로 요청 처리
서버: send_data()로 응답 전송 (예: "HTTP/1.0 200 OK" + index.html)
클라이언트: HTTP Response 수신 및 웹 페이지 표시
연결 종료:
close(client): 클라이언트와의 연결 종료
close(server): 서버 소켓 종료
3) 주요 특징:
서버는 멀티스레드 방식으로 동작하여 여러 클라이언트 요청을 동시 처리
HTTP 프로토콜을 사용하여 요청과 응답을 주고받음
각 연결은 독립적으로 처리되며, 작업 완료 후 연결이 종료됨
