단일 cpu 작업 100m 이 걸린다고 할 때, 순차적 작업은 20% 병렬 가능 작업 80% 가능하다고 하고, cpu 수는 4개 일 때 최적화된 실행 시간은?
- 1000.2 + 1000.8/4 = 20m
#pragma omp parallel for
for(i=0; i<N; i++) {
c[i] = a[i] + b[i];
}
// a[i] + b[i]의 각 연산을 여러 스레드에 분배하여 c 배열을 병렬로 채움
https://woochan-autobiography.tistory.com/207
pthread_t pthread_setcanceltype(int type, int* oldtype)
- PTHREAD_CANCEL_ASYCHRONUS : 호출 시 즉시 종료
- PTHREAD_CANCEL_DEFERED : pthread_testcancel() 호출지점 이후 종료
pthread_t pthread_setcancelstate(int state, int* oldstate)
- PTHREAD_CANCEL_DISABLE : 취소 요청을 받더라도 즉시 취소되지 않고,
취소 요청이 보류(pending) 상태
- PTHREAD_CANCEL_ENABLE : 스레드는 취소 요청을 받는 즉시 해당 요청을 처리
(PTHREAD_CANCEL_ASYNCHRONOUS / PTHREAD_CANCEL_DEFERRED)
UNIX와 UNIX 계열 시스템에서 프로세스에 특정 이벤트가 발생했다는 것을 알리기 위해 사용되는 메커니즘
프로세스가 실행 중인 동안 자체적으로 발생한 이벤트에 의해 생성
외부 이벤트나 다른 프로세스의 행위에 의해 생성
- 사용자가 키보드에서 Ctrl-C를 누르거나 다른 프로세스가 현재 프로세스에
신호를 보내는 경우 비동기적 신호가 발생
pthread_kill(tid, signal)
- 스레드 식별자 tid의 스레드에 signal 신호를 전송
각 스레드가 자신만의 데이터 복사본을 가지고 작업할 수 있도록 하는 메커니즘
TLS를 사용하면 각 스레드가 독립적으로 데이터를 접근하고 수정할 수 있어
데이터 경합이나 동기화 문제를 효과적으로 방지 가능
__thread int tls;
// 주로 전역 변수에 선언
로컬 변수: 함수가 호출될 때 생성되고 함수가 리턴할 때 소멸, 함수 내에서만 접근 가능
TLS: 스레드가 시작될 때 생성되고 스레드가 종료될 때까지 유지, 스레드 내의 어떤 함수에서든 접근 가능
정적 데이터 : 프로세스 내의 모든 스레드 간에 공유
TLS : 변수는 각 스레드에 고유, 쓰레드간 독립적으로 격리 되어있음
스레드 풀을 사용하는 경우와 같이 스레드 생성 과정을 직접 제어할 수 없는 환경에서 TLS는 특히 유용함. 스레드 풀에서는 여러 작업을 동시에 처리할 수 있는 스레드들이 미리 생성되어 있으며, 각 스레드는 재사용될 수 있음. 이런 경우, 각 스레드가 독립적인 작업 상태를 유지해야 하는데 도움을 줌.
clone() 시스템 호출은 리눅스에서 프로세스 또는 스레드를 생성할 때 사용하는 함수
fork()와 유사하지만, clone()은 호출하는 프로세스의 자식 프로세스와 공유할 리소스의 범위를 사용자가 더 세밀하게 제어할 수 있는 옵션을 제공
clone()의 기능과 특징
clone() 함수는 특정 플래그를 사용하여, 자식 프로세스와 공유할 리소스를 정확하게 지정할 수 있음
#define _GNU_SOURCE
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int childFunction(void* arg) {
printf("Child process\n");
return 0;
}
int main() {
const int STACK_SIZE = 65536; // 스택 크기 할당
char* stack = malloc(STACK_SIZE);
if (!stack) {
perror("Failed to allocate stack");
exit(1);
}
// clone() 호출, childFunction을 자식 프로세스의 시작 포인트로 설정
int child_pid = clone(childFunction, stack + STACK_SIZE,
SIGCHLD | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_VM, NULL);
if (child_pid == -1) {
perror("clone");
exit(1);
}
printf("Parent process\n");
wait(NULL); // 자식 프로세스 종료 대기
free(stack);
return 0;
}
//
// SIGCHLD: 자식 프로세스가 종료되었을 때 부모 프로세스에게 SIGCHLD 신호를 보내도록 설정
// CLONE_FS: 파일 시스템 관련 정보를 부모 프로세스와 공유
// CLONE_FILES: 파일 디스크립터를 부모 프로세스와 공유
// CLONE_SIGHAND: 신호 처리기를 부모 프로세스와 공유
// CLONE_VM: 가상 메모리 공간을 부모 프로세스와 공유