C 언어
멀티스레딩은 멀티태스킹의 특수한 형태로, 멀티태스킹은 컴퓨터가 두 개 이상의 프로그램을 동시에 실행할 수 있게 하는 기능입니다. 멀티태스킹에는 프로세스 기반과 스레드 기반 두 가지 유형이 있습니다.
멀티스레드 프로그램은 동시에 실행될 수 있는 두 개 이상의 부분을 포함하며, 각 부분을 스레드라고 하고 각 스레드는 별도의 실행 경로를 정의합니다.
C++에는 멀티스레드 애플리케이션에 대한 내장 지원이 없으며, 전적으로 운영체제에 의존합니다. 이 튜토리얼은 Linux OS를 기준으로 POSIX 스레드(Pthreads)를 사용합니다. Pthreads는 FreeBSD, NetBSD, GNU/Linux, macOS, Solaris 등 많은 유닉스 계열 POSIX 시스템에서 사용 가능한 API를 제공합니다.
POSIX 스레드를 생성하는 루틴:
#include <pthread.h>
pthread_create(thread, attr, start_routine, arg)
pthread_create는 새 스레드를 생성하고 실행 가능하게 만듭니다. 코드 내 어디서든 여러 번 호출할 수 있습니다.
| 번호 | 매개변수 및 설명 |
|---|---|
| 1 | thread 서브루틴이 반환하는 새 스레드의 불투명한 고유 식별자 |
| 2 | attr 스레드 속성을 설정하는 데 사용할 수 있는 불투명한 속성 객체. 기본값은 NULL |
| 3 | start_routine 스레드 생성 후 실행할 C++ 루틴 |
| 4 | argstart_routine에 전달할 단일 인자. void* 타입으로 포인터 캐스트하여 참조로 전달. 인자가 없으면 NULL |
프로세스가 생성할 수 있는 최대 스레드 수는 구현에 따라 다릅니다. 생성된 스레드들은 동등하며 다른 스레드를 생성할 수 있습니다. 스레드 간에는 암묵적 계층 구조나 종속성이 없습니다.
POSIX 스레드를 명시적으로 종료하는 루틴:
#include <pthread.h>
pthread_exit(status)
pthread_exit()는 스레드가 작업을 완료하고 더 이상 필요하지 않을 때 호출합니다. main()이 생성한 스레드들보다 먼저 끝나고 pthread_exit()으로 종료하면 다른 스레드들은 계속 실행됩니다. 그렇지 않으면 main() 종료 시 자동으로 종료됩니다.
#include <iostream>
#include <cstdlib>
#include <pthread.h>
using namespace std;
#define NUM_THREADS 5
void *PrintHello(void *threadid) {
long tid = (long)threadid;
cout << "Hello World! 스레드 ID, " << tid << endl;
pthread_exit(NULL);
}
int main() {
pthread_t threads[NUM_THREADS];
int rc, i;
for (i = 0; i < NUM_THREADS; i++) {
cout << "main(): 스레드 생성 중, " << i << endl;
rc = pthread_create(&threads[i], NULL, PrintHello, (void *)i);
if (rc) {
cout << "오류: 스레드 생성 불가, " << rc << endl;
exit(-1);
}
}
pthread_exit(NULL);
}
컴파일: g++ test.cpp -lpthread
실행 결과:
main() : creating thread, 0
main() : creating thread, 1
main() : creating thread, 2
main() : creating thread, 3
main() : creating thread, 4
Hello World! Thread ID, 0
Hello World! Thread ID, 1
Hello World! Thread ID, 2
Hello World! Thread ID, 3
Hello World! Thread ID, 4
구조체를 사용해 여러 인자를 전달할 수 있습니다. 스레드 콜백은 void*를 가리키므로 모든 데이터 타입을 전달 가능합니다.
#include <iostream>
#include <cstdlib>
#include <pthread.h>
using namespace std;
#define NUM_THREADS 5
struct thread_data {
int thread_id;
char *message;
};
void *PrintHello(void *threadarg) {
struct thread_data *my_data = (struct thread_data *) threadarg;
cout << "스레드 ID: " << my_data->thread_id;
cout << " 메시지: " << my_data->message << endl;
pthread_exit(NULL);
}
int main() {
pthread_t threads[NUM_THREADS];
struct thread_data td[NUM_THREADS];
int rc, i;
for (i = 0; i < NUM_THREADS; i++) {
cout << "main(): 스레드 생성 중, " << i << endl;
td[i].thread_id = i;
td[i].message = "이것은 메시지";
rc = pthread_create(&threads[i], NULL, PrintHello, (void *)&td[i]);
if (rc) {
cout << "오류: 스레드 생성 불가, " << rc << endl;
exit(-1);
}
}
pthread_exit(NULL);
}
스레드를 조인하거나 분리하는 두 루틴:
pthread_join(threadid, status)
pthread_detach(threadid)
pthread_join()은 지정된 스레드가 종료될 때까지 호출 스레드를 블록합니다. 스레드 생성 시 속성 중 하나로 조인 가능 또는 분리 상태가 정의됩니다. 조인 가능으로 생성된 스레드만 조인할 수 있으며, 분리된 스레드는 절대 조인할 수 없습니다.
#include <iostream>
#include <cstdlib>
#include <pthread.h>
#include <unistd.h>
using namespace std;
#define NUM_THREADS 5
void *wait(void *t) {
long tid = (long)t;
sleep(1);
cout << "스레드에서 대기 중" << endl;
cout << "ID가 " << tid << "인 스레드 ... 종료" << endl;
pthread_exit(NULL);
}
int main() {
int rc, i;
pthread_t threads[NUM_THREADS];
pthread_attr_t attr;
void *status;
// 스레드 속성 초기화 및 조인 가능 설정
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
for (i = 0; i < NUM_THREADS; i++) {
cout << "main(): 스레드 생성 중, " << i << endl;
rc = pthread_create(&threads[i], &attr, wait, (void *)i);
if (rc) {
cout << "오류: 스레드 생성 불가, " << rc << endl;
exit(-1);
}
}
// 속성 해제 및 다른 스레드들 대기
pthread_attr_destroy(&attr);
for (i = 0; i < NUM_THREADS; i++) {
rc = pthread_join(threads[i], &status);
if (rc) {
cout << "오류: 조인 불가, " << rc << endl;
exit(-1);
}
cout << "Main: 스레드 ID " << i << " 완료";
cout << " 종료 상태: " << status << endl;
}
cout << "Main: 프로그램 종료." << endl;
pthread_exit(NULL);
}
C 언어
나사는 여전히 기계 산업에서 중요한 역할을 합니다. 나사를 다른 구성요소에 연결하려면 내부 나사산이 필요합니다. 가공 부품 외면에도 나사산 절삭 가능. 나사산은 부품을 저비용으로 쉽게 연결 가능하게 합니다. 제조업체는 수십 가지 다른 유형 패스너용 나사산 제조에 다양한 방법 사용. 이 글에서는 제조에서 나사산 정의, 나사산 유형, 나사 밀링 기술, 주의사항, 장점 소개. 엔지니어링 및 제조에서 나사산(Thread)이란? 나사산은 실린더 또는 원뿔 내면(너트) 또는 외면(나사 또는 볼트)에 형성된 균일 단면 연속 나선형 능선입니다.
올바른 종류의 나사산을 사용하여 체결을 단순하고 신뢰성 있게 만드세요. 따라서 연결 설치에 사용되는 다양한 나사산을 이해하는 것이 중요합니다. 나사산에는 두 가지 주요 유형이 있습니다: 평행 나사산(Parallel Threads)과 테이퍼 나사산(Tapered Threads). 평행 나사산은 평행한 프로파일을 가지며 부품 전체에서 동일한 직경을 유지합니다. 테이퍼 나사산은 나사산 프로파일에 따라 테이퍼지며 부품이 아래로 이동함에 따라 직경이 감소합니다. 평행 나사산 유형에는 BSSP, UN, 메트릭 평행이 있습니다. BSPT, NP