# 실시간 스레드: 생성 및 관리

### Xenomai에서의 실시간 스레드

Xenomai는 리눅스 커널 상에서 동작하는 실시간 운영체제로, 실시간 스레드를 활용하여 엄격한 시간 요구사항을 충족시킨다. Xenomai의 실시간 스레드는 우선순위 기반 스케줄링을 통해 정해진 시간 내에 작업을 완료하도록 설계되었다.

### 실시간 스레드 생성

Xenomai에서 실시간 스레드를 생성하는 기본적인 방법은 `rt_task_create` 함수를 사용하는 것이다. 이 함수의 기본 시그니처는 다음과 같다:

```c
int rt_task_create(
    RT_TASK *task,
    const char *name,
    int stack_size,
    int priority,
    int mode
);
```

각 매개변수의 의미는 다음과 같다:

* `task`: 생성된 RT\_TASK 구조체에 대한 포인터
* `name`: 스레드의 이름
* `stack_size`: 스레드의 스택 크기 (0이면 기본 스택 크기 사용)
* `priority`: 스레드 우선순위 (높을수록 우선순위가 높음)
* `mode`: 실행 모드 플래그

#### 예제 코드

```c
#include <native/task.h>
#include <native/timer.h>
#include <rtdk.h>

void demo_task(void *arg) {
    rt_printf("Hello from Xenomai real-time task!\n");
}

int main(int argc, char *argv[]) {
    RT_TASK demo_task_desc;
    
    rt_task_create(&demo_task_desc, "Demo Task", 0, 50, 0);
    rt_task_start(&demo_task_desc, &demo_task, NULL);
    
    pause();  // Halting main thread to maintain task execution
    
    return 0;
}
```

위 예제에서는 간단한 실시간 스레드를 생성하고 실행하는 방법을 보여준다. `rt_task_create` 함수가 성공하면 `rt_task_start` 함수로 스레드를 시작할 수 있다.

### 실시간 스레드 시작

스레드가 생성된 후에는 `rt_task_start` 함수를 사용하여 스레드를 시작한다:

```c
int rt_task_start(
    RT_TASK *task,
    void (*task_func)(void *cookie),
    void *cookie
);
```

#### 예제 코드

```c
void demo_task(void *arg) {
    rt_printf("Running real-time task\n");
}

/* ... (생략된 코드) ... */

rt_task_start(&demo_task_desc, &demo_task, NULL);
```

### 실시간 스레드 종료

스레드가 더 이상 필요하지 않으면 `rt_task_delete` 함수를 이용하여 스레드를 삭제할 수 있다:

```c
int rt_task_delete(RT_TASK *task);
```

#### 예제 코드

```c
rt_task_delete(&demo_task_desc);
```

스레드를 삭제하면 스레드와 관련된 자원이 모두 해제된다.

### 실시간 스레드 속성 및 제어

스레드의 우선순위와 모드를 동적으로 변경할 수 있다. `rt_task_set_priority` 및 `rt_task_set_mode` 함수를 활용한다.

#### 우선순위 변경

```c
int rt_task_set_priority(RT_TASK *task, int priority);
```

#### 모드 변경

```c
int rt_task_set_mode(
    int clrmask,
    int setmask,
    int *oldmode
);
```

#### 예제 코드

```c
rt_task_set_priority(&demo_task_desc, 60);

int oldmode;
rt_task_set_mode(0, T_LOCK, &oldmode);
```

위 코드는 특정 스레드의 우선순위를 60으로 설정하고, 모드를 변경하는 예제이다.

### 실시간 스레드 동기화

실시간 시스템에서 스레드 간 동기화는 매우 중요하다. Xenomai는 다양한 동기화 메커니즘을 제공한다. 대표적인 메커니즘으로는 뮤텍스, 세마포어, 메시지 큐가 있다.

#### 뮤텍스 사용

뮤텍스는 여러 스레드에서 공통 자원에 대한 접근을 직렬화하는 동기화 도구이다. Xenomai에서는 `RT_MUTEX`을 사용한다.

```c
#include <native/mutex.h>

RT_MUTEX mutex;

void task1(void *arg) {
    rt_mutex_acquire(&mutex, TM_INFINITE);
    rt_printf("Task 1 acquired mutex\n");
    rt_task_sleep(1000000000);  // 1 second
    rt_mutex_release(&mutex);
}

void task2(void *arg) {
    rt_mutex_acquire(&mutex, TM_INFINITE);
    rt_printf("Task 2 acquired mutex\n");
    rt_task_sleep(1000000000);  // 1 second
    rt_mutex_release(&mutex);
}

int main(int argc, char *argv[]) {
    RT_TASK task1_desc, task2_desc;

    rt_mutex_create(&mutex, "MyMutex");
    rt_task_create(&task1_desc, "Task1", 0, 50, 0);
    rt_task_create(&task2_desc, "Task2", 0, 50, 0);
    rt_task_start(&task1_desc, &task1, NULL);
    rt_task_start(&task2_desc, &task2, NULL);

    pause();  // Halting main thread

    rt_mutex_delete(&mutex);
    return 0;
}
```

#### 세마포어 사용

세마포어는 일정한 개수의 자원에 대한 접근을 제어하는 동기화 도구이다. Xenomai에서는 `RT_SEM`을 사용한다.

```c
#include <native/sem.h>

RT_SEM sem;

void semaphore_task(void *arg) {
    rt_sem_p(&sem, TM_INFINITE);
    rt_printf("Semaphore acquired by task\n");
    rt_task_sleep(1000000000);
    rt_sem_v(&sem);
}

int main(int argc, char *argv[]) {
    RT_TASK task1_desc, task2_desc;

    rt_sem_create(&sem, "MySem", 1, S_FIFO);
    rt_task_create(&task1_desc, "Task1", 0, 50, 0);
    rt_task_create(&task2_desc, "Task2", 0, 50, 0);
    rt_task_start(&task1_desc, &semaphore_task, NULL);
    rt_task_start(&task2_desc, &semaphore_task, NULL);

    pause();  // Halting main thread

    rt_sem_delete(&sem);
    return 0;
}
```

#### 메시지 큐 사용

메시지 큐는 스레드 간 데이터를 전송하는 데 사용된다. Xenomai에서는 `RT_QUEUE`를 제공한다.

```c
#include <native/queue.h>

#define QUEUE_SIZE 512

RT_QUEUE queue;

void sender_task(void *arg) {
    char message[] = "Hello from sender";
    rt_queue_write(&queue, &message, sizeof(message), Q_NORMAL);
    rt_printf("Message sent: %s\n", message);
}

void receiver_task(void *arg) {
    char *msg;
    int size = rt_queue_read(&queue, &msg, TM_INFINITE);
    if (size > 0) {
        rt_printf("Message received: %s\n", msg);
        rt_queue_free(&queue, msg);
    }
}

int main(int argc, char *argv[]) {
    RT_TASK sender_task_desc, receiver_task_desc;

    rt_queue_create(&queue, "MyQueue", QUEUE_SIZE, Q_UNLIMITED, Q_FIFO);
    rt_task_create(&sender_task_desc, "Sender", 0, 50, 0);
    rt_task_create(&receiver_task_desc, "Receiver", 0, 50, 0);
    rt_task_start(&sender_task_desc, &sender_task, NULL);
    rt_task_start(&receiver_task_desc, &receiver_task, NULL);

    pause();  // Halting main thread

    rt_queue_delete(&queue);
    return 0;
}
```

이와 같이 Xenomai에서 제공하는 다양한 동기화 메커니즘을 사용하여 실시간 스레드 간의 상호작용 및 자원 접근을 제어할 수 있다.
