2007년 11월 12일
리눅스 - pthread 프로그래밍
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
#define MAX_QUEUE_SIZE 2000
typedef struct{
typedef struct{
pthread_mutex_t mutex_lock;
int controlAuthority = 0;
void* readThread(void *); // 연 파일의 포인터를 받아 NULL이 될때까지 읽고 그것을 큐에 저장하는 함수
void* writeThread(void *); // 큐에서 하나씩 하나씩 빼내는 함수
void error(char *); // 에러를 내고, 무슨 에러인지 메시지를 출력하는 함수
void init(QueueType *); // 큐를 초기화
int isEmpty(QueueType *); // 큐가 비어있을 때
int isFull(QueueType *); // 큐가 꽉 차있을 때
void enQueue(QueueType *, char); // 큐에 값을 집어넣는 함수
char deQueue(QueueType *); // 큐에서 값을 빼내어 리턴하는 함수
int
main()
{
void*
readThread(void *forarg)
{
void*
writeThread(void *q)
{
void
error(char *msg)
{
void
init(QueueType *q)
{
int
isEmpty(QueueType *q)
{
int
isFull(QueueType *q)
{
void
enQueue(QueueType *q, char item)
{
char
deQueue(QueueType *q){
pthread_ create를 이용한 프로그래밍이다.
read쓰레드와 write쓰레드를 이용하여 read쓰레드는 파일로부터 한 캐릭터를 읽어
queue에 저장하고, write쓰레드는 queue로부터 하나를 pop하여 stdout으로 출력해주는 프로그램이다.
쓰레드상의 동기화 문제, 크리티컬 섹션 문제때문에 상호배제를 하여야 하고
때문에 사용한 것이 pthread_mutex_lock과 unlock 두가지인데
뮤텍스 변수를 선언하고 그것을 초기화 한다음에 lock()과 unlock()사이에 들어간
코드의 변수에는 어떤 쓰레드도 접근하지 못하도록 막는 것이 뮤텍스의 역할이다.
내가 요구한 사항은 캐릭터 하나를 읽으면 하나를 쓰는 (stdout에) 것이었으므로
접근권한을 나타내는 접근권한 플래그를 하나 두었다.
어떻게 보면 이놈도 락을 거는거니까 뮤텍스라고 볼 수 있을라나..?
모르겠다.
날코드인데 pthread_create와 pthread_mutex_lock 함수들에 대해 약간의
이해를 돕는데 꽤 유용한 코드같아 남겨본다.
2차 수정, 소스 사용은 자유입니다만 출처는 반드시 적어주시기 바랍니다.
#include <stdio.h>
#include <pthread.h>
#define MAX_QUEUE_SIZE 2000
typedef struct{
char queue[MAX_QUEUE_SIZE];
int front, rear;
}QueueType; // 사용하기 위한 큐타입 구조체 int front, rear;
typedef struct{
QueueType *q;
FILE *fp;
}forArg; FILE *fp;
pthread_mutex_t mutex_lock;
int controlAuthority = 0;
void* readThread(void *); // 연 파일의 포인터를 받아 NULL이 될때까지 읽고 그것을 큐에 저장하는 함수
void* writeThread(void *); // 큐에서 하나씩 하나씩 빼내는 함수
void error(char *); // 에러를 내고, 무슨 에러인지 메시지를 출력하는 함수
void init(QueueType *); // 큐를 초기화
int isEmpty(QueueType *); // 큐가 비어있을 때
int isFull(QueueType *); // 큐가 꽉 차있을 때
void enQueue(QueueType *, char); // 큐에 값을 집어넣는 함수
char deQueue(QueueType *); // 큐에서 값을 빼내어 리턴하는 함수
int
main()
{
FILE *fp; // 파일 포인터 선언
pthread_t readT,writeT; // read Thread, write Thread 선언
QueueType q={0}; // 사용할 큐 선언, 초기화
forArg a={0}; // 아규먼트값으로 넘길 구조체 선언, 초기화
init(&q); //큐 초기화
pthread_mutex_init(&mutex_lock,NULL); // 뮤텍스 초기화
fp = fopen("source.txt","r+"); // 읽을 파일을 오픈한다
a.q = &q; // 사용할 큐 구조체의 레퍼런스를 아규먼트 구조체에 넘겨줌
a.fp = fp; // 오픈한 파일의 포인터를 아규먼트 구조체에 넘겨줌.
if(pthread_create(&readT,NULL,readThread,(void *)&a) != 0) // 읽기 쓰레드 생성
exit(1);
if(pthread_create(&writeT,NULL,writeThread,(void *)&q) != 0) // 쓰기 쓰레드 생성
exit(1);
pthread_join(writeT,NULL); // 쓰레드 끝날때까지 기다림.
pthread_join(readT,NULL); // 쓰레드 끝날때까지 기다림
fclose(fp); // 파일포인터 닫기.
return 0;
} pthread_t readT,writeT; // read Thread, write Thread 선언
QueueType q={0}; // 사용할 큐 선언, 초기화
forArg a={0}; // 아규먼트값으로 넘길 구조체 선언, 초기화
init(&q); //큐 초기화
pthread_mutex_init(&mutex_lock,NULL); // 뮤텍스 초기화
fp = fopen("source.txt","r+"); // 읽을 파일을 오픈한다
a.q = &q; // 사용할 큐 구조체의 레퍼런스를 아규먼트 구조체에 넘겨줌
a.fp = fp; // 오픈한 파일의 포인터를 아규먼트 구조체에 넘겨줌.
if(pthread_create(&readT,NULL,readThread,(void *)&a) != 0) // 읽기 쓰레드 생성
exit(1);
if(pthread_create(&writeT,NULL,writeThread,(void *)&q) != 0) // 쓰기 쓰레드 생성
exit(1);
pthread_join(writeT,NULL); // 쓰레드 끝날때까지 기다림.
pthread_join(readT,NULL); // 쓰레드 끝날때까지 기다림
fclose(fp); // 파일포인터 닫기.
return 0;
void*
readThread(void *forarg)
{
char ch;
while((ch = fgetc(((forArg*)forarg)->fp)) != EOF) // 파일이 끝이 되기 전까지 한글자를 읽어
{
printf("readThread end\n");
sleep(1);
controlAuthority = 1;
} while((ch = fgetc(((forArg*)forarg)->fp)) != EOF) // 파일이 끝이 되기 전까지 한글자를 읽어
{
rejoin:
if(controlAuthority == 0)
{
else
{
} if(controlAuthority == 0)
{
pthread_mutex_lock(&mutex_lock);
enQueue(((forArg*)forarg)->q,ch); // 큐에 집어넣는다
fprintf(stdout,"read 1 character: %c\n",ch);// 넣었다고 출력한다.
controlAuthority = 1;
pthread_mutex_unlock(&mutex_lock);
} enQueue(((forArg*)forarg)->q,ch); // 큐에 집어넣는다
fprintf(stdout,"read 1 character: %c\n",ch);// 넣었다고 출력한다.
controlAuthority = 1;
pthread_mutex_unlock(&mutex_lock);
else
{
sleep(1);
goto rejoin;
} goto rejoin;
printf("readThread end\n");
sleep(1);
controlAuthority = 1;
void*
writeThread(void *q)
{
char ch;
int emptyFlag = 0;
for(;;)
{
if(emptyFlag == 1)
{
} int emptyFlag = 0;
for(;;)
{
rejoin2:
if(controlAuthority == 1)// 권한이 있고 read쪽에서 락을 풀어야만 접근할 수 있다.
{
else
{
} if(controlAuthority == 1)// 권한이 있고 read쪽에서 락을 풀어야만 접근할 수 있다.
{
ch = deQueue(((QueueType*)q)); // 하나를 빼서 ch에 집어넣는다
if(ch == EOF) // 큐가 다 비면.
{
else
{
} if(ch == EOF) // 큐가 다 비면.
{
emptyFlag = 1;
break;
} break;
else
{
fprintf(stdout,"Write : %c\n",ch); // 읽은 문자를 출력한다.
controlAuthority = 0;
} controlAuthority = 0;
else
{
sleep(1);
goto
rejoin2;
} goto
rejoin2;
if(emptyFlag == 1)
{
error("Queue is Empty!!\n");
} void
error(char *msg)
{
fprintf(stderr,"%s",msg); // 에러메시지 출력
exit(0); // 프로그램 종료.
} exit(0); // 프로그램 종료.
void
init(QueueType *q)
{
q->front = q->rear = 0; // 처음이랑 끝이 0 // 초기화
} int
isEmpty(QueueType *q)
{
return (q->front == q->rear); // 만약에 처음이랑 끝이 같으면 1을 리턴 (에러에 써먹을것)
} int
isFull(QueueType *q)
{
return ((q->rear+1)%MAX_QUEUE_SIZE == q->front); // 끝 + 1이랑 처음이 같으면 1을 리턴 ( 에러에 써먹을 것)
} void
enQueue(QueueType *q, char item)
{
if(isFull(q)) // full 시에 에러처리
error("Queue is Full!\n"); // 꽉찼다고 말해준다.
q->rear = (q->rear+1) % MAX_QUEUE_SIZE; // 집어넣으면 끝의 인덱스를 바꿔준다
q->queue[q->rear] = item; // 바꾼 인덱스에 값을 넣어준다.
} error("Queue is Full!\n"); // 꽉찼다고 말해준다.
q->rear = (q->rear+1) % MAX_QUEUE_SIZE; // 집어넣으면 끝의 인덱스를 바꿔준다
q->queue[q->rear] = item; // 바꾼 인덱스에 값을 넣어준다.
char
deQueue(QueueType *q){
if(isEmpty(q)) // empty 시에 에러처리
{
q->front = (q->front+1) % MAX_QUEUE_SIZE; // 처음을 증가시키고
return q->queue[q->front]; // 증가된 값[인덱스]의 값을 빼내 리턴해준다.
}{
return EOF;
} q->front = (q->front+1) % MAX_QUEUE_SIZE; // 처음을 증가시키고
return q->queue[q->front]; // 증가된 값[인덱스]의 값을 빼내 리턴해준다.
pthread_ create를 이용한 프로그래밍이다.
read쓰레드와 write쓰레드를 이용하여 read쓰레드는 파일로부터 한 캐릭터를 읽어
queue에 저장하고, write쓰레드는 queue로부터 하나를 pop하여 stdout으로 출력해주는 프로그램이다.
쓰레드상의 동기화 문제, 크리티컬 섹션 문제때문에 상호배제를 하여야 하고
때문에 사용한 것이 pthread_mutex_lock과 unlock 두가지인데
뮤텍스 변수를 선언하고 그것을 초기화 한다음에 lock()과 unlock()사이에 들어간
코드의 변수에는 어떤 쓰레드도 접근하지 못하도록 막는 것이 뮤텍스의 역할이다.
내가 요구한 사항은 캐릭터 하나를 읽으면 하나를 쓰는 (stdout에) 것이었으므로
접근권한을 나타내는 접근권한 플래그를 하나 두었다.
어떻게 보면 이놈도 락을 거는거니까 뮤텍스라고 볼 수 있을라나..?
모르겠다.
날코드인데 pthread_create와 pthread_mutex_lock 함수들에 대해 약간의
이해를 돕는데 꽤 유용한 코드같아 남겨본다.
2차 수정, 소스 사용은 자유입니다만 출처는 반드시 적어주시기 바랍니다.
# by | 2007/11/12 15:18 | STUDY | 트랙백 | 덧글(0)




☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]