우분투에서 동작하는 message queue 방식의 IPC 예제 프로그램을 작성 하였다.
client에서 char를 보내고 server에서 이를 받아 1초마다 출력하는 아주 간단한 코드이다.
server.cpp
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define MAX_TEXT 100
struct msg_buffer {
long msg_type;
char msg_text[MAX_TEXT];
};
volatile bool g_aborted = false;
volatile bool g_print = false;
int msgid;
char output_char = 'A'; // Default output character
void *message_receiver(void *arg);
int main() {
key_t key;
pthread_t tid;
std::cout << "start test server !!" << std::endl;
// Generate unique key for IPC
if ((key = ftok(".", 173)) == -1) {
perror("ftok");
exit(1);
}
// Create message queue
if ((msgid = msgget(key, 0666 | IPC_CREAT)) == -1) {
perror("msgget");
exit(1);
}
// Create thread to handle message receiving
if (pthread_create(&tid, NULL, message_receiver, NULL) != 0) {
perror("pthread_create");
exit(1);
}
// Main thread: Output the current char every second
while (not g_aborted) {
if (g_print)
std::cout << output_char << std::endl;
sleep(1);
}
std::cout << "exit test server !!" << std::endl;
return 0;
}
void *message_receiver(void *arg) {
struct msg_buffer msg {};
while (true) {
// Receive message from client
if (msgrcv(msgid, &msg, sizeof(msg.msg_text), 1, 0) == -1) {
perror("msgrcv");
exit(1);
}
// Update output character
output_char = msg.msg_text[0];
if (output_char == 'Z') {
g_aborted = true;
break;
}
else if (output_char == 'P') {
g_print = not g_print;
}
}
pthread_exit(nullptr);
}
char 출력은 main loop에서 처리하고, ipc message 수신을 위한 thread를 생성하였다. 'P' char를 받으면 출력 여부를 toggle 하고, 'Z' char를 받으면 종료한다.
반응형
client.cpp
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define MAX_TEXT 100
struct msg_buffer {
long msg_type;
char msg_text[MAX_TEXT];
};
int main(int argc, char *argv[]) {
int msgid;
struct msg_buffer msg {};
if (argc != 2) {
fprintf(stderr, "Usage: %s <character>\n", argv[0]);
exit(1);
}
key_t key;
if ((key = ftok(".", 173)) == -1) {
perror("ftok");
exit(1);
}
if ((msgid = msgget(key, 0666 | IPC_CREAT)) == -1) {
perror("msgget");
exit(1);
}
strncpy(msg.msg_text, argv[1], MAX_TEXT);
msg.msg_text[MAX_TEXT - 1] = '\0'; // ensure null-terminated string
msg.msg_type = 1;
if (msgsnd(msgid, &msg, sizeof(msg.msg_text), 0) == -1) {
perror("msgsnd");
exit(1);
}
std::cout << "sent to server: " << msg.msg_text[0] << std::endl;
return 0;
}
실행시 argument로 char를 받는다.
태그는 C++을 달았지만, cout을 제외하면 사실상 C 코드이다.
각각을 빌드하여 먼서 server를 background에서 실행하고, client를 통해 char를 전달하면 의도한 대로 잘 동작한다.
ipcs 명령으로 message queue를 확인해 볼 수 있다.
다음번엔 이걸 systemd 에 등록하여 service로 동작시켜볼까 한다.
반응형
'프로그래밍 > etc' 카테고리의 다른 글
[Ubuntu] systemd service 등록하기 (0) | 2024.08.06 |
---|---|
맥 잠자기 방지 cmd (0) | 2024.05.05 |
mosquitto "Connection error: Connection Refused: identifier rejected." 오류 (0) | 2024.02.21 |
Mac 주요 단축키 모음 (0) | 2023.11.25 |
nvidia GPU 정보 확인 (ubuntu) (0) | 2023.07.06 |