C를 사용하여 여러 스레딩 예제를 작성하려고합니다. 이는 사용자로부터 가져 오는 숫자이고 두 스레드의 합계입니다.
스레드는 앞뒤 및 뒤에서 앞으로 서로 직접 떨어져 있습니다.
세마포어를 사용하여 전역 변수를 관리하고 있지만 출력에 세마포가 제대로 작동하지 않는 것으로 표시됩니다.
뭐가 잘못 되었 니?
코드 출력 :
Array size? :10
Array of contents? :4 2 8 1 5 3 7 9 6 10
Thread_1 > read 4, sum is = 4
Thread_1 > read 2, sum is = 6
Thread_1 > read 8, sum is = 14
Thread_1 > read 1, sum is = 15
Thread_1 > read 5, sum is = 20
Thread_1 > read 3, sum is = 23
Thread_1 > read 7, sum is = 30
Thread_1 > read 9, sum is = 39
Thread_1 > read 6, sum is = 45
Thread_1 > read 10, sum is = 55
Thread_1 > End.
Thread_2 > End.
코드 :
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <semaphore.h>
int *array; //Global integer array
int sum; //Global sum variable
int counter = 0;
sem_t mutex;
void *front_to_back( void *val )
{
int SIZE;
SIZE = *((int *) val);
while (1)
{
sem_wait(&mutex);
if( counter != SIZE )
{
sum = sum + array[counter];
printf("Thread_1 > read %d, sum is = %d \n", array[counter], sum);
counter++;
}else
{
printf("Thread_1 > End. \n");
sem_post(&mutex);
break;
}
sem_post(&mutex);
}
}
void *back_to_front( void *val )
{
int SIZE;
SIZE = *((int *) val);
int i=1;
while (1)
{
sem_wait(&mutex);
if( counter != SIZE )
{
sum = sum + array[SIZE - i];
printf("Thread_2 > read %d, sum is = %d \n", array[SIZE - i], sum);
counter++;
i++;
}else
{
printf("Thread_2 > End. \n");
sem_post(&mutex);
break;
}
sem_post(&mutex);
}
}
main(){
int SIZE;
printf("Array size? :");
scanf("%d", &SIZE);
array = malloc(SIZE*sizeof(int));
int i=0;
printf("Array of contents? :");
for (i ; i<SIZE ; i++)
{
scanf("%d", &array[i]);
}
pthread_t t[2];
sem_init(&mutex, 0, 1);
pthread_create(&t[1], NULL, front_to_back, (void *) &SIZE );
pthread_create(&t[2], NULL, back_to_front, (void *) &SIZE );
pthread_join(t[1],NULL);
pthread_join(t[2],NULL);
free(array);
sem_destroy(&mutex);
}
당신은 사용해야 t[0]
과 t[1]
에 main()
: 크기의 배열이 N
유효한 인덱스에있다 0..N-1
, 그래서 먼저, 수정이 있습니다. 올바른 코드는 다음과 같습니다.
pthread_create(&t[0], NULL, front_to_back, (void *) &SIZE );
pthread_create(&t[1], NULL, back_to_front, (void *) &SIZE );
pthread_join(t[0],NULL);
pthread_join(t[1],NULL);
이상적으로, 당신은 또한 여부를 확인해야 malloc()
하고 pthread_create()
성공. 이러한 함수는 오류와 함께 반환 될 수 있으므로 처리해야합니다. 코드는 오류를 무시합니다 (범위를 벗어난 액세스를 사용하면 실제로 작동하는 것이 운이 좋습니다).
또한 뮤텍스 인 것처럼 세마포어를 사용하는 이유는 무엇입니까? 여기서 세마포어는 실제로 필요하지 않습니다. 세마포어의 성능과 유연성이 필요하지 않을 때는 뮤텍스를 사용하십시오. 한 가지 중요한 차이점은 세마포를 사용하면 한 스레드에서 대기하고 다른 스레드에 게시 할 수있는 반면 뮤텍스는이를 획득 한 스레드에 의해 잠금 해제되어야한다는 것입니다.
따라서 뮤텍스로 충분한 세마포어를 사용하면 코드의 오류를 덮을 수 있습니다. 그래서 저는 계속해서 뮤텍스를 대신 사용하겠습니다. 모든 변경 사항이 적용된 코드는 다음과 같습니다.
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
int *array; //Global integer array
int sum; //Global sum variable
int counter = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void *front_to_back( void *val )
{
int SIZE;
SIZE = *((int *) val);
while (1)
{
pthread_mutex_lock(&mutex);
if( counter != SIZE )
{
sum = sum + array[counter];
printf("Thread_1 > read %d, sum is = %d \n", array[counter], sum);
counter++;
}else
{
printf("Thread_1 > End. \n");
pthread_mutex_unlock(&mutex);
break;
}
pthread_mutex_unlock(&mutex);
}
return NULL;
}
void *back_to_front( void *val )
{
int SIZE;
SIZE = *((int *) val);
int i=1;
while (1)
{
pthread_mutex_lock(&mutex);
if( counter != SIZE )
{
sum = sum + array[SIZE - i];
printf("Thread_2 > read %d, sum is = %d \n", array[SIZE - i], sum);
counter++;
i++;
}else
{
printf("Thread_2 > End. \n");
pthread_mutex_unlock(&mutex);
break;
}
pthread_mutex_unlock(&mutex);
}
return NULL;
}
int main(void) {
int SIZE;
printf("Array size? :");
scanf("%d", &SIZE);
array = malloc(SIZE*sizeof(int));
int i=0;
printf("Array of contents? :");
for (; i<SIZE ; i++)
{
scanf("%d", &array[i]);
}
pthread_t t[2];
pthread_create(&t[0], NULL, front_to_back, (void *) &SIZE );
pthread_create(&t[1], NULL, back_to_front, (void *) &SIZE );
pthread_join(t[0],NULL);
pthread_join(t[1],NULL);
free(array);
return 0;
}
첫눈에 코드에 다른 문제가 보이지 않습니다.
이제 문제는 병렬 처리가 보이지 않는다는 것입니다. 더 큰 배열로 시도해야합니다. 단일 스레드는 컨텍스트 전환 전에 10 개의 요소 배열을 처리 할 수 있습니다.
업데이트 : 방금 3000 요소 배열로 코드를 시도했습니다. 병렬로 실행되는 것을 명확하게 볼 수 있습니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다