오늘은 Wiring Pi의 Thread를 알아볼 예정이며, 이 과정에서 C언어로 Threading을 제작하는 방법도 알아볼 예정이다.
#include <stdio.h>
#include <wiringPi.h>
// LED Pin - wiringPi pin 0 is BCM_GPIO 17.
#define LED 0
PI_THREAD (blinky)
{
for (;;)
{
digitalWrite (LED, HIGH) ; // On
delay (500) ; // mS
digitalWrite (LED, LOW) ; // Off
delay (500) ;
}
}
int main (void)
{
printf ("Raspberry Pi blink\n") ;
wiringPiSetup () ;
pinMode (LED, OUTPUT) ;
piThreadCreate (blinky) ;
for (;;)
{
printf ("Hello, world\n") ;
delay (600) ;
}
return 0 ;
}
이 코드를 통해 Main에서는 600ms 마다 Hello World를, 그리고 Thread에서는 Blinky를 따로 돌릴 것으로 보인다.
digitalWrite, pinMode는 이미 보았으니 이번에는
PI_THREAD와 piThreadCreate를 살펴보자!
1. piThreadCreate(void *(*fn) (void *))
int piThreadCreate (void *(*fn)(void *))
{
pthread_t myThread ;
return pthread_create (&myThread, NULL, fn, NULL) ;
}
이 piThreadCreate 함수는 piThread.c에 정의되어 있으며, 함수 포인터로 pthread를 생성하는 역할을 한다.
참고로, pthread_create 함수는
int WINPTHREAD_API pthread_create(pthread_t *th, const pthread_attr_t *attr, void *(* func)(void *), void *arg);
와 같이 정의되어 있으며, 여기서 myThread가 지역변수여도 큰 상관이 없다.
중요한 것은 func을 이어주는 Function 포인터인것!
2. PI_THREAD(X)
#define PI_THREAD(X) void *X (UNU void *dummy)
이 PI_THREAD의 근원에 좀 더 가까이 가보니, 다음과 같은 것들을 알아내었다.
#define UNU __attribute__((unused))
#define __attribute__(x) /* nothing */
사실 여기부터는 잘 모르겠어서, 우선 GPT에게 물어보았다.
#define PI_THREAD(X) void *X (UNU void *dummy)
➡ 이 매크로를 사용하면 스레드 함수의 형식을 표준화할 수 있습니다.
➡ 즉, PI_THREAD(myThread)는 다음과 동일하게 변환됩니다.
void *myThread(UNU void *dummy);
➡ 이 코드는 POSIX 스레드(pthread_create())와 함께 사용할 수 있는 함수 형태로 변환됩니다.
➡ pthread_create()는 다음과 같은 함수 포인터를 요구합니다.
void *(*start_routine) (void *);
➡ 따라서 PI_THREAD()를 사용하면 스레드 함수의 형식을 강제할 수 있습니다.
그래서 추측하기로는 변화는 다음과 같을 것으로 보인다.
1. 매크로 사용 하 PI_THREAD(blinky) 변화
void *blinky (UNU void *dummy)
2. 해당 과정에 있어 자동적으로 함수 내용 Follow
void *blinky(__attribute__((unused)) void *dummy) {
for (;;) {
digitalWrite(LED, HIGH); // On
delay(500);
digitalWrite(LED, LOW); // Off
delay(500);
}
}
이렇게 pthread의 일반적인 정의 방식대로 blinky가 정의되고, 이를 pthread_create에 들어가서 작동하게 된다.
여기까지 해서 thread가 정의되고, 작동하는 이유까지 알아보았다.
이와 관련하여
- thread는 무엇인지
- 함수 포인터는 무엇이고 어떻게 쓰이는지
- raspberry pi에 있어 thread는 과연 멀티 프로세싱인지 멀티쓰레드인지
- 쓰레드가 1개 코어에서만 돌아가는지
등 알아봐야 할 것이 더 늘었다...
아무래도 몇개는 CS 지식을 정리하며 진행하는 것이 좋아보인다!
'CS 지식 정리 > 라즈베리파이-C언어' 카테고리의 다른 글
| Wiring Pi - PWM.c 분석 (0) | 2025.03.18 |
|---|---|
| Wiring Pi - ISR.c (인터럽트 서비스 루틴) 분석 (0) | 2025.03.14 |
| Wiring Pi 파헤치기 (1) 예제부터 차근차근 알아보기 (0) | 2025.03.07 |
| 라즈베리파이를 C언어로 컨트롤하자 - 레지스터 직접 접근 방법 이해 (0) | 2025.02.25 |