Mutex lock과 condition을 사용한 생산자 소비자 문제의 구현
Posted 2007/12/26 22:31■ 문제 정의
|
Pthread Ringbuffer(생산자, 소비자 문제)를 mutex lock과 condition을 사용하여 구현하시오 |
■ 문제 해결
1. Thread의 Life Time
2. 전역변수를 사용하여 process간 통신
- Thread는 자신에게 별도로 주어진 Stack Point 외에 다른 영역들을 모두 공유한다.
- 생산자와 소비자 문제에서는 thread간 전역변수로 Array와 Count를 선언하여 데이터를 공유한다.
3. critical section 문제 해결
- 전역변수에 값을 Write하려 할 때 critical section 문제가 발생할 수 있다.
- 각 thread가 동시에 값을 적을 수 없도록 mutex_lock을 사용하여 먼저 문을 잠그고 Critical Section에 접근하도록 한다.
<그림3 : Process간의 공유변수 접근>
<그림4 : Mutual Exclusion>
4. pthread_cond_wait과 pthread_cond_signal 사용으로 동기화
- Int pthread_cond_wait(pthread_cond_t* cond, pthread_mutex_t* mutex);
• 지정된 condition이 signal될 때 까지 호출 스레드를 대기시키는 함수로, 반드시 입력 인수 mutex가 locked된 상태에서 호출되어야 하며, 호출되면 자동으로 mutex를 unlock하고 대기한다. 호출된 스레드가 signal에 의해 깨어날 때에는 mutex는 다시 lock이 걸린 상태로 반환된다.
• Producer는 공유 Data Array가 꽉 찼을 때 Wait되어 Consumer의 소비를 기다린다.
• Consumer는 공유 Data Array가 비었을 때 Wait되어 Producer의 생산을 기다린다.
- int pthread_cond_signal(pthread_cond_t* cond);
• pthread_cond_t 변수로 buffer_has_space와 buffer_has_data를 둬서 동기화를 시킨다.
• pthread_cond_wait()으로 대기하는 스레드를 깨우는 함수이다. 이 함수도 mutex가 lock된 상태에서 호출되어야 한다.
• pthread_cond_wait()에 의한 대기 스레드가 없는 상태에서의 pthread_cond_signal() 호출은 컨디션이나 스레드들에게 아무런 영향을 미치지 않는다.
• cond_signal은 스택(stack) 되지 않는다.
• Producer는 물건을 생산할 때 마다 공유하는 Data Array가 비어있지 않다는 의미로 Signal을 보내고 만약 Consumer가 Block되어 있다면 깨워주고, 그렇지 않을 경우 Signal은 아무런 영향을 미치지 않는다.
• Consumer는 물건을 소비할 때 마다 공유하는 Data Array가 꽉 차있지 않다는 의미로 Signal을 보내고 만약 Producer가 Block되어 있다면 깨워주고, 그렇지 않을 경우 Signal은 아무런 영향을 미치지 않는다.
5. Pthread의 Join과 소멸
- pthread가 수행이 끝나면 pthread_join으로 2개의 Thread를 하나로 합쳐준다. 그리고 pthread_exit로 합쳐진 하나의 thread를 소멸시킨다.
6. Pthread_cond의 소멸
- Mutual Exclusion때 동기화의 목적으로 사용한 Pthread_cond타입의 객체는 pthread_cond_destroy함수를 통해 소멸시킨다.
■ 소 스
|
void* producer(void* arg); void* consumer(void* arg); int buffer[100]; // 버퍼의 크기는 100 int count=0; // 버퍼안의 원소의 개수는 0개 int in=-1; // Producer가 생산한 물건을 넣을 인덱스 int out=-1; // Consumer가 생산된 물건을 가져갈 인덱스 // Critical Section을 위한 Mutex Lock 선언 및 조기화 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // Mutual Exclusion을 위한 Condtion 선언 및 초기화 pthread_cond_t buffer_has_space = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t buffer_has_data = PTHREAD_MUTEX_INITIALIZER; int main(void) { int i;
// Producer와 Consumer 2개의 Thread를 생성한다. pthread_t threads[2]; pthread_create(&threads[0], NULL, producer, NULL); pthread_create(&threads[1], NULL, consumer, NULL); // 2개의 Thread가 수행을 마치고 Join되기를 기다린다. for(i=0 ; i<2 ; i++) pthread_join(threads[i], NULL); // Mutual Exclusion에 사용한 Condition을 소멸시킨다. pthread_cond_destroy(&buffer_has_space); pthread_cond_destroy(&buffer_has_data); // Thread를 소멸시킨다. pthread_exit(NULL); return 0; } // Producer Thread가 수행할 메인 함수 void* producer(void* arg) { int i; // 물건 1000개를 생산한다. for(i=0 ; i<1000 ; i++) { // 생산한 물건을 출력한다. printf("producer data = %d\n", i); // 공유변수에 접근하기 전에 Mutex_Lock을 건다. pthread_mutex_lock(&mutex); // 버퍼의 개수가 꽉 찼다면 Consumer가 물건을 하나 소비할 때 까지 기다린다. if(count == 100) pthread_cond_wait(&buffer_has_space, &mutex); // 생산한 물건을 버퍼에 넣는다. in++; in %= 100; buffer[in] = i; count++; // 버퍼가 비어있지 않다는 의미의 Signal을 보낸다. pthread_cond_signal(&buffer_has_data); // Mutex Lock을 해지한다. pthread_mutex_unlock(&mutex); } } // Consumer Thread가 수행할 메인함수 void* consumer(void* arg) { int i, data; // 물건 1000개를 소비한다. for(i=0 ; i<1000 ; i++) { // 공유변수에 접근하기 전에 Mutex_Lock을 건다. pthread_mutex_lock(&mutex); // 버퍼의 개수가 비어있다면 Producer가 물건을 하나 생산할 때 까지 기다린다. if(count == 0) pthread_cond_wait(&buffer_has_data, &mutex); // 버퍼로부터 물건을 하나 소비한다. out++; out %= 100; data = buffer[out]; count--; // 버퍼가 꽉차지 않았다는 의미의 Signal을 보낸다. pthread_cond_signal(&buffer_has_space); // Mutex Lock을 해지한다. pthread_mutex_unlock(&mutex); // 소비한 물건을 출력한다. printf(" consumer data = %d\n", data); } } |
■ 결과화면
1. 결과1
|
순서1 |
순서2 |
|
producer data = 957 producer data = 958 producer data = 959 producer data = 960 producer data = 961 producer data = 962 producer data = 963 producer data = 964 producer data = 965 producer data = 966 producer data = 967 producer data = 968 producer data = 969 producer data = 970 producer data = 971 producer data = 972 producer data = 973 producer data = 974 producer data = 975 producer data = 976 producer data = 977 producer data = 978 producer data = 979 producer data = 980 producer data = 981 producer data = 982 producer data = 983 producer data = 984 producer data = 985 consumer data = 885 consumer data = 886 consumer data = 887 consumer data = 888 consumer data = 889 consumer data = 890 consumer data = 891 consumer data = 892 consumer data = 893 consumer data = 894 consumer data = 895 consumer data = 896 consumer data = 897 consumer data = 898 consumer data = 899 consumer data = 900 consumer data = 901 consumer data = 902 consumer data = 903 consumer data = 904 consumer data = 905 consumer data = 906 consumer data = 907 consumer data = 908 consumer data = 909 consumer data = 910 consumer data = 911 consumer data = 912 consumer data = 913 consumer data = 914 consumer data = 915 consumer data = 916 consumer data = 917 consumer data = 918 consumer data = 919 consumer data = 920 consumer data = 921 consumer data = 922 consumer data = 923 consumer data = 924 consumer data = 925 consumer data = 926 consumer data = 927 consumer data = 928 consumer data = 929 consumer data = 930 consumer data = 931 consumer data = 932 consumer data = 933 consumer data = 934 consumer data = 935 |
consumer data = 936 consumer data = 937 consumer data = 938 consumer data = 939 consumer data = 940 consumer data = 941 consumer data = 942 consumer data = 943 consumer data = 944 consumer data = 945 consumer data = 946 consumer data = 947 consumer data = 948 consumer data = 949 consumer data = 950 consumer data = 951 consumer data = 952 consumer data = 953 consumer data = 954 consumer data = 955 consumer data = 956 consumer data = 957 consumer data = 958 consumer data = 959 consumer data = 960 consumer data = 961 consumer data = 962 consumer data = 963 consumer data = 964 consumer data = 965 consumer data = 966 consumer data = 967 consumer data = 968 consumer data = 969 consumer data = 970 consumer data = 971 consumer data = 972 consumer data = 973 consumer data = 974 consumer data = 975 consumer data = 976 consumer data = 977 consumer data = 978 consumer data = 979 consumer data = 980 consumer data = 981 consumer data = 982 consumer data = 983 consumer data = 984 consumer data = 985 producer data = 986 producer data = 987 producer data = 988 producer data = 989 producer data = 990 producer data = 991 producer data = 992 producer data = 993 producer data = 994 producer data = 995 producer data = 996 producer data = 997 producer data = 998 producer data = 999 consumer data = 986 consumer data = 987 consumer data = 988 consumer data = 989 consumer data = 990 consumer data = 991 consumer data = 992 consumer data = 993 consumer data = 994 consumer data = 995 consumer data = 996 consumer data = 997 consumer data = 998 consumer data = 999 |
2. 결과2
|
순서1 |
순서2 |
|
consumer data = 894 producer data = 895 consumer data = 895 producer data = 896 consumer data = 896 producer data = 897 consumer data = 897 producer data = 898 consumer data = 898 producer data = 899 consumer data = 899 producer data = 900 consumer data = 900 producer data = 901 consumer data = 901 producer data = 902 consumer data = 902 producer data = 903 consumer data = 903 producer data = 904 consumer data = 904 producer data = 905 consumer data = 905 producer data = 906 consumer data = 906 producer data = 907 consumer data = 907 producer data = 908 consumer data = 908 producer data = 909 consumer data = 909 producer data = 910 consumer data = 910 producer data = 911 consumer data = 911 producer data = 912 consumer data = 912 producer data = 913 consumer data = 913 producer data = 914 consumer data = 914 producer data = 915 consumer data = 915 producer data = 916 consumer data = 916 producer data = 917 consumer data = 917 producer data = 918 consumer data = 918 producer data = 919 consumer data = 919 producer data = 920 consumer data = 920 producer data = 921 consumer data = 921 producer data = 922 consumer data = 922 producer data = 923 consumer data = 923 producer data = 924 consumer data = 924 producer data = 925 consumer data = 925 producer data = 926 consumer data = 926 producer data = 927 consumer data = 927 producer data = 928 consumer data = 928 producer data = 929 consumer data = 929 producer data = 930 consumer data = 930 producer data = 931 consumer data = 931 producer data = 932 consumer data = 932 producer data = 933 consumer data = 933 producer data = 934 consumer data = 934 producer data = 935 consumer data = 935 producer data = 936 consumer data = 936 producer data = 937 consumer data = 937 producer data = 938 consumer data = 938 producer data = 939 consumer data = 939 producer data = 940 consumer data = 940 producer data = 941 consumer data = 941 producer data = 942 consumer data = 942 producer data = 943 consumer data = 943 producer data = 944 consumer data = 944 producer data = 945 consumer data = 945 producer data = 946 consumer data = 946 |
producer data = 947 consumer data = 947 producer data = 948 consumer data = 948 producer data = 949 consumer data = 949 producer data = 950 consumer data = 950 producer data = 951 consumer data = 951 producer data = 952 consumer data = 952 producer data = 953 consumer data = 953 producer data = 954 consumer data = 954 producer data = 955 consumer data = 955 producer data = 956 consumer data = 956 producer data = 957 consumer data = 957 producer data = 958 consumer data = 958 producer data = 959 consumer data = 959 producer data = 960 consumer data = 960 producer data = 961 consumer data = 961 producer data = 962 consumer data = 962 producer data = 963 consumer data = 963 producer data = 964 consumer data = 964 producer data = 965 consumer data = 965 producer data = 966 consumer data = 966 producer data = 967 consumer data = 967 producer data = 968 consumer data = 968 producer data = 969 consumer data = 969 producer data = 970 consumer data = 970 producer data = 971 consumer data = 971 producer data = 972 consumer data = 972 producer data = 973 consumer data = 973 producer data = 974 consumer data = 974 producer data = 975 consumer data = 975 producer data = 976 consumer data = 976 producer data = 977 consumer data = 977 producer data = 978 consumer data = 978 producer data = 979 consumer data = 979 producer data = 980 consumer data = 980 producer data = 981 consumer data = 981 producer data = 982 consumer data = 982 producer data = 983 consumer data = 983 producer data = 984 consumer data = 984 producer data = 985 consumer data = 985 producer data = 986 consumer data = 986 producer data = 987 consumer data = 987 producer data = 988 consumer data = 988 producer data = 989 consumer data = 989 producer data = 990 consumer data = 990 producer data = 991 consumer data = 991 producer data = 992 consumer data = 992 producer data = 993 consumer data = 993 producer data = 994 consumer data = 994 producer data = 995 consumer data = 995 producer data = 996 consumer data = 996 producer data = 997 consumer data = 997 producer data = 998 consumer data = 998 producer data = 999 consumer data = 999 |
'C.S.E > Linux' 카테고리의 다른 글
| LINUX에서 X-STATION 작업환경 만들기 (0) | 2008/03/29 |
|---|---|
| POSIX Semaphore를 이용한 생산자 / 소비자 문제 구현 (0) | 2007/12/26 |
| Mutex lock과 condition을 사용한 생산자 소비자 문제의 구현 (0) | 2007/12/26 |
| 제 7회 KELP 공개 세미나 후기 - 3 (0) | 2007/11/11 |
| 제 7회 KELP 공개 세미나 후기 - 1 (0) | 2007/11/10 |
| 리눅스 시동파일 (0) | 2007/07/11 |
- Filed under : C.S.E/Linux
- Comment Trackback
이올린에 북마크하기