# 13주차 1214 강의 요약
## Thread
프로세스: 서로 독립적인 메모리로 할당
쓰레드: 한 프로그램 내에서 독립적으로 실행하고 싶을 때 만들 수 있음
리눅스에서는 쓰레드 프로그램을 어떻게 하는가?
### p1.c
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
// 독립적으로 수행해야 하는 함수의 형식은 이런 형식이어야 한다 -> void * 형식이어야 한다
void *func(void *arg){
int i;
for(i=0; i<5; i++){
printf("It is working \n");
sleep(1);
}
}
void *func2(void *arg){
int i;
for(i=0; i<5; i++){
printf("It is working2 \n");
sleep(1);
}
}
int main(){
pthread_t thrd1, thrd2; // 쓰레드 아이디 생성
int result, status;
result = pthread_create(&thrd1, NULL, func, NULL); //쓰레드 생성
result = pthread_create(&thrd2, NULL, func2, NULL); //쓰레드 생성
for(int i=0; i<10; i++){
printf("Main work .. \n");
usleep(500000); //0.5초
}
pthread_join(thrd1, &status); //내가 만든 쓰레드가 끝나길 기다리고 결과를 status에 담아라
pthread_join(thrd2, &status); //thrd2가 끝나길 기다림.. 없으면? main이 먼저 끝나버리게 되면 하던 일을 다 못하고 프로그램이 종료됨
}
### bash shell
gcc p1.c -o p1 -lpthread
./p1
main함수와 fun함수가 동시에 실행됨
쓰레드를 생성하면 code, static, stack, heap영역을 모두 공유, stack영역만 쪼개서 씀 -> 쓰레드를 위한 스택을 별도로 잡아둠
### prime.c
하나의 쓰레드로 수행하면 n이 커지게 되면 시간이 매우 오래 걸림 .. -> multi thread가 필요!
// 소수의 개수를 구하는 알고리즘 -> n이 매우 커지면 시간이 오래 걸림
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
int isPrime(int n){
for(int i=2; i<=n/2; i++){
if (n%i==0){
return 0;
}
}
return 1;
}
int main(){
int n;
int count;
printf("Enter a positive integer : ");
scanf("%d", &n);
count=0;
//2~n까지 소수의 개수 구하기
for(int i=2; i<=n; i++){
if(isPrime(i)){
count++;
}
}
printf("The number of prime number is %d. \n", count);
}
### primethread.c
구간을 나눠서 두 개의 함수를 사용하여 두 개의 쓰레드로 실행. 독립적으로 수행
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
int isPrime(int n){
for(int i=2; i<=n/2; i++){
if (n%i==0){
return 0;
}
}
return 1;
}
int n;
// 쓰레드 함수는 형식이 정해져 있음
void *prime_count1(void *arg){
int count=0;
for(int i=2; i<=n/2; i++){
if (isPrime(i)){count++;}
}
pthread_exit(count); //return 대신. 결과값(count)을 던져주면..
}
void *prime_count2(void *arg){
int count=0;
for(int i=n/2+1; i<=n; i++){
if (isPrime(i)){count++;}
}
pthread_exit(count); //return 대신
}
int main(){
int status;
pthread_t thrd1, thrd2;
printf("Enter a positive integer : ");
scanf("%d", &n);
pthread_create(&thrd1, NULL, prime_count1, NULL);
pthread_create(&thrd2, NULL, prime_count2, NULL);
pthread_join(thrd1, &status); // 함수에서 결과값을 던져주면 status에 결과값이 저장됨
printf("status = %d \n", status);
pthread_join(thrd2, &status);
printf("status = %d \n", status);
}
### primethread2.c
함수 하나로 여러 개의 쓰레드 생성하여 실행
구조체를 생성해서 구간을 나눠서 실행
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
// 구조체 생성
struct PrimeTestRange{
int startN;
int endN;
};
int isPrime(int n){
for(int i=2; i<=n/2; i++){
if (n%i==0){
return 0;
}
}
return 1;
}
int n;
int total_count=0;
// 쓰레드 함수는 형식이 정해져 있음
//두 개 이상의 쓰레드가 동시에 읽고 써서 race condition이 발생할 수 있음!!
void *prime_count(void *arg){
struct PrimeTestRange range;
range = *(struct PrimeTestRange*)arg;
for(int i=range.startN; i<=range.endN; i++){
if (isPrime(i)){total_count++;}
}
}
int main(){
int status;
pthread_t thrd1, thrd2;
struct PrimeTestRange r1, r2;
printf("Enter a positive integer : ");
scanf("%d", &n);
r1.startN=2;
r1.endN=n/2;
r2.startN=n/2+1;
r2.endN=n;
pthread_create(&thrd1, NULL, prime_count, &r1);
pthread_create(&thrd2, NULL, prime_count, &r2);
pthread_join(thrd1, &status); // 함수에서 결과값을 던져주면 status에 결과값이 저장됨
pthread_join(thrd2, &status);
printf("The number of prime numbers is %d \n", total_count);
}
오류 발생! 동시에 전역변수에 접근하게 되어 예상한 결과가 나오지 않음!! -> race condition
=> 이를 해결하기 위해 semaphore가 필요!!

## mutex lock
mutex lock: mutual exclusive lock
mutex lock을 사용한 multi thread
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
// 구조체 생성
struct PrimeTestRange{
int startN;
int endN;
};
int isPrime(int n){
for(int i=2; i<=n/2; i++){
if (n%i==0){
return 0;
}
}
return 1;
}
int n;
int total_count=0;
pthread_mutex_t count_lock;
// 쓰레드 함수는 형식이 정해져 있음
//두 개 이상의 쓰레드가 동시에 읽고 써서 race condition이 발생할 수 있음!! -> mutex lock이 필요
void *prime_count(void *arg){
int count=0;
struct PrimeTestRange range;
range = *(struct PrimeTestRange*)arg;
for(int i=range.startN; i<=range.endN; i++){
if (isPrime(i)){
count++;
}
}
pthread_mutex_lock (&count_lock); //lock-X
total_count+=count;
pthread_mutex_unlock(&count_lock); //unlock-x
}
int main(){
int status;
pthread_t thrd1, thrd2;
struct PrimeTestRange r1, r2;
printf("Enter a positive integer : ");
scanf("%d", &n);
r1.startN=2;
r1.endN=n/2;
r2.startN=n/2+1;
r2.endN=n;
pthread_create(&thrd1, NULL, prime_count, &r1);
pthread_create(&thrd2, NULL, prime_count, &r2);
pthread_join(thrd1, &status); // 함수에서 결과값을 던져주면 status에 결과값이 저장됨
pthread_join(thrd2, &status);
printf("The number of prime numbers is %d \n", total_count);
}
=> dead lock이 발생할 가능성이 있음!!
'Linux' 카테고리의 다른 글
[Linux] semaphore (0) | 2022.12.12 |
---|---|
[Linux] message queue, shared memory (0) | 2022.12.12 |
[Linux] fork, pipe, mkfifo (0) | 2022.12.11 |
[Linux] programming shell, execvp, fork (0) | 2022.12.09 |