이 글은 이런 것에 대한 정보를 담고 있다
- pthread에 대한 내용
- pthread에서 lock 구현하는 법
- websocketpp 라이브러리를 활용한 프로젝트에서 lock을 사용하는법.
이런 것에 대한 정보는 담겨있지 않다
- 뮤텍스와, 세마포어, 크리티컬 섹션등의 상세한 비교
- 스레드 사용에 대한 심화 설명
1. pthread란 무엇인가.
프로그래밍에서 필수라고 할 수 있는 멀티스레딩을 위한 라이브러리이다. 유닉스와 리눅스 계열 프로그래밍에서 사용 가능하며 윈도우에서도 호환되는 라이브러리를 설치하면 사용할 수 있다. C++에서는
#include <pthread.h>
코드를 추가함으로써 사용할 수 있다. 다만 pthread 대신 다른 스레드 라이브러리를 사용하기 위해선 thread 라이브러리나 window.h 라이브러리를 include해서 비슷한 기능으로 대체할 수 있다.
2. pthread에서 lock구현하는법
- 일단 pthread의 mutex객체를 하나 생성한다
pthread_mutex_t lock;
int shared_resource = 0;
- 뮤텍스 초기화 코드를 호출한다
pthread_mutex_init(&lock, NULL);
- 특정 자원을 사용해야하는 함수에서 lock 함수를 호출한다
pthread_mutex_lock(&lock);
shared_resource++;
pthread_mutex_unlock(&lock);
그 함수가 끝나기 전데 unlock을 반드시 걸어줘야한다.
3. websocketpp 라이브러리를 활용한 프로젝트에서 lock을 사용하는법
현재 C++에서 웹소켓 서버를 제작하는 일을 하는 중인데. 이를 위해 websocketpp 라이브러리를 사용하고있다. 이 라이브러리도 멀티스레드 환경을 고려해서 thread lock으로 동시성을 제어한다.
class WebsocketServer
{
public:
static bool init();
static void run();
static void stop();
static bool sendClose(string id);
static bool sendData(string id, string data);
private:
static bool getWebsocket(const string &id, websocketpp::connection_hdl &hdl)
{
auto socket = websockets.find(id);
if (socket != websockets.end())
{
hdl = socket->second;
return true;
}
return false;
};
static websocketpp::server<websocketpp::config::asio> server;
static pthread_rwlock_t websocketsLock;
static map<string, websocketpp::connection_hdl> websockets;
static LogStream ls;
static ostream os;
// callbacks
static bool on_validate(websocketpp::connection_hdl hdl);
static void on_fail(websocketpp::connection_hdl hdl);
static void on_close(websocketpp::connection_hdl hdl);
static void on_message(websocketpp::connection_hdl hdl, websocketpp::server<websocketpp::config::asio>::message_ptr msg);
};
웹소켓 서버의 기능들을 한번 래핑한 클래스다 이 클래스를 통해서 특정 포트를 리슨하고 클라이언트와 상호작용 할 수 있다. 웹소켓 서버는 기본적으로 여러개의 클라이언트와 상호작용하기 때문에 string을 키로 삼고 웹소켓 연결 핸들을 value로 삼는 map 자료구조 websockets을 생성했다.
그런데 여러 스레드에서 동시에 이 websockets을 참조하거나 변경할경우 문제가 발생할 수 있기 때문에 라이브러리가 만들어 놓은 pthread_rwlock_t 객체를 하나 생성한다.
그리고 클라이언트가 연결될 때 훅으로 걸리는 on_validate 코드에서
WebsocketServer::on_validate(connection_hdl hdl){
...
if (pthread_rwlock_wrlock(&websocketsLock) != 0)
{
return false;
// Failed to write-lock websocketsLock.
}
websockets.insert(std::pair<string, connection_hdl>(id, hdl));
if (pthread_rwlock_unlock(&websocketsLock) != 0)
{
return false;
// Failed to unlock websocketsLock.
}
}
websockets객체에 insert를 하기전에 websocketsLock을 잠구는 함수가 실패했을 경우 즉 현재 사용중일경우 쓰기를 취소하고 끝난뒤에는 unlock에 실패했을경우 각각 에러를 리턴한다.
'CS연구소👨💻' 카테고리의 다른 글
EC2-NGINX-도커-젠킨스 설정 (0) | 2024.11.06 |
---|---|
[C++] template <1> (8) | 2024.09.07 |
[C++] 입출력 스트림 (0) | 2024.07.08 |
[C++] 예외 처리 (0) | 2024.06.26 |
[C++] 다형성과 오버로딩, 오버라이딩 (0) | 2024.06.22 |