Notice
Recent Posts
Recent Comments
250x250
Creative Code
Chapter18(쓰레드,세마포어,mutex) 본문
728x90
※thread1.c파일
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
void* thread_main(void *arg);
int main(int argc, char *argv[])
{
pthread_t t_id; // 쓰레드 식별자
int thread_param = 5; // 쓰레드에 전달할 인자
if (pthread_create(&t_id, NULL, thread_main, (void*)&thread_param) != 0)
{
puts("pthread_create() error");
return -1;
}
// 메인 쓰레드가 10초 동안 대기
sleep(10);
puts("end of main");
return 0;
}
void* thread_main(void *arg)
{
int i;
int cnt = *((int*)arg); // 쓰레드에 전달된 인자를 정수로 변환
// 주어진 횟수만큼 반복하면서 "running thread"를 출력하고 1초 대기
for (i = 0; i < cnt; i++)
{
sleep(1);
puts("running thread");
}
return NULL;
}
※thread2.c파일
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
void* thread_main(void *arg);
int main(int argc, char *argv[])
{
pthread_t t_id;
int thread_param = 5;
void *thr_ret; // 쓰레드의 반환 값을 저장하기 위한 포인터
// 쓰레드 생성
if (pthread_create(&t_id, NULL, thread_main, (void*)&thread_param) != 0)
{
puts("pthread_create() error");
return -1;
}
// 쓰레드가 종료될 때까지 대기하고 반환 값을 받음
if (pthread_join(t_id, &thr_ret) != 0)
{
puts("pthread_join() error");
return -1;
}
// 쓰레드의 반환 값을 출력
printf("Thread return message: %s\n", (char*)thr_ret);
free(thr_ret); // 동적으로 할당한 메모리를 해제
return 0;
}
void* thread_main(void *arg)
{
int i;
int cnt = *((int*)arg);
char *msg = (char*)malloc(sizeof(char) * 50);
strcpy(msg, "Hello, I'm thread~\n"); // 메시지를 할당하고 복사
for (i = 0; i < cnt; i++)
{
sleep(1);
puts("running thread");
}
// 쓰레드의 반환 값으로 메시지를 반환 (메인 쓰레드에서 해제해야 함)
return (void*)msg;
}
※thread3.c파일
#include <stdio.h>
#include <pthread.h>
// 전역 변수로 합을 저장할 변수 선언
int sum = 0;
// 쓰레드 함수 원형 선언
void* thread_summation(void* arg);
int main(int argc, char* argv[])
{
pthread_t id_t1, id_t2;
int range1[] = {1, 5};
int range2[] = {6, 10};
// 첫 번째 쓰레드 생성 및 실행
pthread_create(&id_t1, NULL, thread_summation, (void*)range1);
// 두 번째 쓰레드 생성 및 실행
pthread_create(&id_t2, NULL, thread_summation, (void*)range2);
// 두 쓰레드의 실행이 완료될 때까지 대기
pthread_join(id_t1, NULL);
pthread_join(id_t2, NULL);
// 결과 출력
printf("result: %d\n", sum);
return 0;
}
// 쓰레드 함수 정의
void* thread_summation(void* arg)
{
int start = ((int*)arg)[0];
int end = ((int*)arg)[1];
while (start <= end)
{
sum += start;
start++;
}
return NULL;
}
※thread4.c파일
#include <stdio.h>
#include <pthread.h>
#define NUM_THREAD 100
// 두 가지 타입의 쓰레드 함수 원형 선언
void *thread_inc(void *arg);
void *thread_des(void *arg);
// 전역 변수로 사용할 long long 타입의 변수 선언
long long num = 0;
// 쓰레드 동기화를 위한 mutex 선언
pthread_mutex_t mutex;
int main(int argc, char *argv[])
{
pthread_t thread_id[NUM_THREAD];
int i;
// mutex 초기화
pthread_mutex_init(&mutex, NULL);
printf("sizeof long long: %d\n", sizeof(long long));
// NUM_THREAD 수만큼의 쓰레드를 생성하고 실행
for (i = 0; i < NUM_THREAD; i++)
{
if (i % 2) {
// 홀수 인덱스의 쓰레드는 "thread_inc" 함수 실행
pthread_create(&(thread_id[i]), NULL, thread_inc, NULL);
}
else {
// 짝수 인덱스의 쓰레드는 "thread_des" 함수 실행
pthread_create(&(thread_id[i]), NULL, thread_des, NULL);
}
}
// 모든 쓰레드의 실행이 완료될 때까지 대기
for (i = 0; i < NUM_THREAD; i++) {
pthread_join(thread_id[i], NULL);
}
// 결과 출력
printf("result: %lld\n", num);
// mutex 해제
pthread_mutex_destroy(&mutex);
return 0;
}
// "thread_inc" 함수 정의: num을 증가시키는 함수
void *thread_inc(void *arg)
{
int i;
// mutex를 사용하여 동기화
pthread_mutex_lock(&mutex);
for (i = 0; i < 50000000; i++) {
num += 1;
}
// mutex 해제
pthread_mutex_unlock(&mutex);
return NULL;
}
// "thread_des" 함수 정의: num을 감소시키는 함수
void *thread_des(void *arg)
{
int i;
// mutex를 사용하여 동기화
pthread_mutex_lock(&mutex);
for (i = 0; i < 50000000; i++) {
num -= 1;
}
// mutex 해제
pthread_mutex_unlock(&mutex);
return NULL;
}
※semaphore.c파일
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
void * read(void * arg);
void * accu(void * arg);
static sem_t sem_one;
static sem_t sem_two;
static int num;
int main(int argc, char *argv[])
{
pthread_t id_t1, id_t2;
sem_init(&sem_one, 0 /*기본 값*/, 0 /*생성되는 세마포어의 초기 값*/);
sem_init(&sem_two, 0 /*기본 값*/, 1 /*생성되는 세마포어의 초기 값*/);
pthread_create(&id_t1, NULL, read, NULL);
pthread_create(&id_t2, NULL, accu, NULL);
pthread_join(id_t1, NULL);
pthread_join(id_t2, NULL);
sem_destroy(&sem_one);
sem_destroy(&sem_two);
return 0;
}
void * read(void * arg)
{
int i;
for(i=0; i<5; i++)
{
fputs("Input num: ", stdout);
// -(빼기)
sem_wait(&sem_two);
scanf("%d", &num);
// +(더하기)
sem_post(&sem_one);
}
return NULL;
}
void * accu(void * arg)
{
int sum=0, i;
for(i=0; i<5; i++)
{
sem_wait(&sem_one);
sum+=num;
sem_post(&sem_two);
}
printf("Result: %d \n", sum);
return NULL;
}
※thread5.c파일
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>
void* thread_main1(void *arg);
void* thread_main2(void *arg);
void* thread_main3(void *arg);
// 세 개의 세마포어를 선언
static sem_t sem_one;
static sem_t sem_two;
static sem_t sem_thr;
int main(int argc, char *argv[])
{
pthread_t t1_id, t2_id, t3_id;
int thread_param = 5;
// 세마포어 초기화
sem_init(&sem_one, 0, 0); // 초기 값 0
sem_init(&sem_two, 0, 0); // 초기 값 0
sem_init(&sem_thr, 0, 1); // 초기 값 1
pthread_create(&t1_id, NULL, thread_main1, (void*)&thread_param);
pthread_create(&t2_id, NULL, thread_main2, (void*)&thread_param);
pthread_create(&t3_id, NULL, thread_main3, (void*)&thread_param);
pthread_join(t1_id, NULL);
pthread_join(t2_id, NULL);
pthread_join(t3_id, NULL);
// 세마포어 해제
sem_destroy(&sem_one);
sem_destroy(&sem_two);
sem_destroy(&sem_thr);
sleep(1);
puts("end of main");
return 0;
}
void* thread_main1(void *arg)
{
int i;
int cnt = *((int*)arg);
for (i = 0; i < cnt; i++)
{
sleep(1);
sem_wait(&sem_one); // sem_one 세마포어 대기
puts("running thread1");
sem_post(&sem_thr); // sem_thr 세마포어 해제
}
return NULL;
}
void* thread_main2(void *arg)
{
int i;
int cnt = *((int*)arg);
for (i = 0; i < cnt; i++)
{
sleep(1);
sem_wait(&sem_two); // sem_two 세마포어 대기
puts("running thread2");
sem_post(&sem_one); // sem_one 세마포어 해제
}
return NULL;
}
void* thread_main3(void *arg)
{
int i;
int cnt = *((int*)arg);
for (i = 0; i < cnt; i++)
{
sleep(1);
sem_wait(&sem_thr); // sem_thr 세마포어 대기
puts("running thread3");
sem_post(&sem_two); // sem_two 세마포어 해제
}
return NULL;
}
※echo_server.c파일
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <pthread.h>
#define BUF_SIZE 1024
#define NUM_THREAD 5
void error_handling(char *message);
void* thread_main(void* arg);
int main(int argc, char *argv[])
{
int serv_sock, clnt_sock;
char message[BUF_SIZE];
int str_len, i;
pthread_t thread_id[NUM_THREAD];
struct sockaddr_in serv_adr;
struct sockaddr_in clnt_adr;
socklen_t clnt_adr_sz;
if(argc!=2) {
printf("Usage : %s <port>\n", argv[0]);
exit(1);
}
serv_sock=socket(PF_INET, SOCK_STREAM, 0);
if(serv_sock==-1)
error_handling("socket() error");
memset(&serv_adr, 0, sizeof(serv_adr));
serv_adr.sin_family=AF_INET;
serv_adr.sin_addr.s_addr=htonl(INADDR_ANY);
serv_adr.sin_port=htons(atoi(argv[1]));
if(bind(serv_sock, (struct sockaddr*)&serv_adr, sizeof(serv_adr))==-1)
error_handling("bind() error");
if(listen(serv_sock, 5)==-1)
error_handling("listen() error");
clnt_adr_sz=sizeof(clnt_adr);
for(i=0; i<5; i++)
{
clnt_sock=accept(serv_sock, (struct sockaddr*)&clnt_adr, &clnt_adr_sz);
if(clnt_sock==-1)
error_handling("accept() error");
else
printf("Connected client %d \n", i+1);
// 새로운 쓰레드를 생성하고 클라이언트 소켓을 인자로 전달
pthread_create(&thread_id[i], NULL, thread_main, (void*)&clnt_sock);
// 쓰레드를 백그라운드에서 실행 (non-blocking)
pthread_detach(thread_id[i]);
}
close(serv_sock);
return 0;
}
void error_handling(char *message)
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
void* thread_main(void* arg) {
int str_len;
int clnt = *((int*)arg);
char message[BUF_SIZE];
while((str_len=read(clnt, message, BUF_SIZE))!=0)
write(clnt, message, str_len);
return NULL;
}
728x90
'TCP IP 소켓프로그래밍' 카테고리의 다른 글
Chapter8(호스트 정보 조회) (1) | 2023.10.11 |
---|---|
Chapter9(버퍼 입력받기) (0) | 2023.10.11 |
Chapter5(echo_client) (0) | 2023.10.11 |
Chapter4(서버에 순차접속) (0) | 2023.10.11 |
Chapter3(서버에 접속한 IP주소, 포트번호 출력) (0) | 2023.10.10 |