스마트 인재개발원/3차프로젝트

(광주인공지능학원) 3차프로젝트 멀티쓰레드 설계 및 울음소리 분석

광주인공지능학원 스마트인재개발원의 3차프로젝트 1주 남은 상황...

모션감지 및 울음소리 CNN분석이 끝났다. 

광주인공지능학원에서의 팀원들과 마지막 7일을 밤을 새며 작업중이다. 

 

오늘은 쓰레드 포스팅이다.. 정말 어려운 부분이다..

1. 음성레코드함수

def record():
    global room 
    global cry

    while(True):

        if os.path.isfile('file.wav'):
            os.remove('file.wav')
        FORMAT = pyaudio.paInt16
        CHANNELS = 1
        RATE = 44100
        CHUNK = 1024
        RECORD_SECONDS = 5
        WAVE_OUTPUT_FILENAME = "file.wav"

        audio = pyaudio.PyAudio()
        # start Recording
        stream = audio.open(format=pyaudio.paInt16, 
                        channels=CHANNELS, 
                        rate=RATE, 
                        input=True, 
                        input_device_index=1,
                        frames_per_buffer=CHUNK)

        print("recording...")
        frames = []

        for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
            data = stream.read(CHUNK)
            frames.append(data)
        print("finished recording")
        # stop Recording
        
        stream.stop_stream()
        waveFile = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
        waveFile.setnchannels(CHANNELS)
        waveFile.setsampwidth(audio.get_sample_size(FORMAT))
        waveFile.setframerate(RATE)
        waveFile.writeframes(b''.join(frames))
        waveFile.close()
        room = print_room_prediction()
        cry = print_cry_prediction()
        sleep(3)
        stream.stop_stream()
        stream.close()
        audio.terminate()

 

2.  파이어베이스 메세지 함수

def sendMessage(body, title):
    # 메시지 (data 타입)
    data_message = {
        "값": body,
        "타이틀": title
     }
 
    # 토큰값을 이용해 1명에게 푸시알림을 전송함
    result = push_service.single_device_data_message(registration_id=TOKEN, data_message=data_message)
 
    # 전송 결과 출력
    print(result)

3. 모션체킹과 뒤집기 함수

def motion_check_func():
    while(1):
        if motion_check_flag == 0:
            print("첫번쨰 모션 없음")   
            # sendMessage("움직임:", "아이움직임 없음" )        
            sleep(8)
            if motion_check_flag == 0:
                    print("두번째 모션 없음")
                    sleep(6)
                    if motion_check_flag == 0:
                        print("세번째 모션 없음")
                        sleep(4)
                        if motion_check_flag == 0:
                            print("20초동안 움직임 없음")
                            sendMessage("2", "뒤집기감지")
                            sleep(10)
        else :
            print("모션감지")
            
def back_try_func():
    global back_over_check_flag
    while(1):
        if back_over_check_flag == 0:
            print("첫번쨰 뒤집기감지")
            sleep(5)
            if back_over_check_flag == 0:
                    print()
                    sendMessage("1", "뒤집기감지")
                    sleep(5)
                    if back_over_check_flag == 0:
                        sendMessage("1", "뒤집기감지")
                        print("세번째 모션 없음")

        else :
            print("뒤집지 않음")

4. 피쳐 추출 함수

def extract_features(file_name):
    max_ped_len = 217
    audio, sample_rate = librosa.load(file_name, res_type='kaiser_fast') 
    mfccs = librosa.feature.mfcc(y=audio, sr=sample_rate, n_mfcc=40)
    pad_width = max_ped_len - mfccs.shape[1]
    mfccs = np.pad(mfccs, pad_width=((0, 0), (0, pad_width)), mode='constant')
    mfccs = mfccs.reshape(1, 40, 217, 1)
    
    return mfccs

5. 방안울음 감지 함수

def print_room_prediction():
    file_name = 'hunger1.wav'
    num_rows = 40
    num_columns = 217
    num_channels = 1
    model = load_model('./save_models/room_model.h5')
    prediction_feature = extract_features(file_name)
    predicted_vector = model.predict_classes(prediction_feature)
    if (str(predicted_vector) == "[0]"):
        return '방안상태 : 울음'        
    elif(str(predicted_vector) == "[1]"):
        return '방안상태 : 웃음'    
    elif(str(predicted_vector) == "[2]"):
        return '방안상태 : 시끄러움'    
    elif(str(predicted_vector) == "[3]"):
        return '방안상태 : 조용함'    

#    print("The Room predicted class is:", predicted_vector, '\n') 
    
    return predicted_vector

6.  울음 분석 함수

def print_cry_prediction():
    file_name = 'hunger1.wav'
    num_rows = 40
    num_columns = 217
    num_channels = 1
    model = load_model('./save_models/cry_model.h5')
    prediction_feature = extract_features(file_name)
    predicted_vector = model.predict_classes(prediction_feature)
    if (str(predicted_vector) == "[0]"):
        return '울음분석 : 배고픔'        
    elif(str(predicted_vector) == "[1]"):
        return '울음분석 : 고통'    
    elif(str(predicted_vector) == "[2]"):
        return '울음분석 : 피곤함'    
    elif(str(predicted_vector) == "[3]"):
        return '울음분석 : 트림'    
    elif(str(predicted_vector) == "[4]"):
        return '울음분석 : 불편함'  
#    print("The Cry predicted class is:", predicted_vector, '\n') 
    
    return predicted_vector

7. 모션 디텍트 함수

def motion():
    global back_over_check_flag
    global motion_check_flag
    global start_time
    mp_drawing = mp.solutions.drawing_utils
    mp_pose = mp.solutions.pose
    cap = cv2.VideoCapture("res/back2.mp4")

    counter = 0 
    stage = None
    time = 0

    left_elbow_list = []
    right_elbow_list = []
    left_knee_list = []
    right_knee_list = []
    music_count = 0
    
    with mp_pose.Pose(min_detection_confidence=0.5, min_tracking_confidence=0.5) as pose:
        ret, a = cap.read()
        ret, b = cap.read()
        while cap.isOpened():
            ret, frame = cap.read()    


            image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            image.flags.writeable = False 
            results = pose.process(image)
            image.flags.writeable = True
            image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)

            image = Image.fromarray(image)
            draw = ImageDraw.Draw(image)
            draw.text((10, 60), str(room), font=ImageFont.truetype("./fonts/ONE Mobile Regular.ttf", 25), fill=(255,255,255))
            image = np.array(image)
            


            now = datetime.datetime.now()
            current_time = now.strftime("%Y/%D %H:%M:%S")
            image = Image.fromarray(image)
            draw = ImageDraw.Draw(image)
            draw.text((10, 10), current_time , font=ImageFont.truetype("./fonts/ONE Mobile Regular.ttf", 15), fill=(255,255,255))
            image = np.array(image)

            #cv2.putText(image, str(room), (100,100),  cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 0, 0), 2, cv2.LINE_AA)
            motion_check_num = motion_detect(a,b,frame, image)
            a = b
            b = frame
            if motion_check_num == 0 :
                image = Image.fromarray(image)
                draw = ImageDraw.Draw(image)
                draw.text((10, 30), "모션감지", font=ImageFont.truetype("./fonts/ONE Mobile Regular.ttf", 25), fill=(255,255,255))
                image = np.array(image)
                motion_check_flag = 1
            
            else : 
                image = Image.fromarray(image)
                draw = ImageDraw.Draw(image)
                draw.text((10, 30), "모션없음", font=ImageFont.truetype("./fonts/ONE Mobile Regular.ttf", 25), fill=(255,255,255))
                image = np.array(image)
                motion_check_flag = 0

            if (str(room) == '방안상태 : 울음'):
                image = Image.fromarray(image)
                draw = ImageDraw.Draw(image)
                draw.text((10, 90), str(cry), font=ImageFont.truetype("./fonts/ONE Mobile Regular.ttf", 25), fill=(255,255,255))
                image = np.array(image)               
                if (music_count == 50):
                    playsound_check = True
                else: 
                    music_count +=1
                
            try:
                landmarks = results.pose_landmarks.landmark

                left_shoulder = [landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value].x,landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value].y]
                left_elbow = [landmarks[mp_pose.PoseLandmark.LEFT_ELBOW.value].x,landmarks[mp_pose.PoseLandmark.LEFT_ELBOW.value].y]
                left_wrist = [landmarks[mp_pose.PoseLandmark.LEFT_WRIST.value].x,landmarks[mp_pose.PoseLandmark.LEFT_WRIST.value].y]
                left_elbow_angle = calculate_angle(left_shoulder, left_elbow, left_wrist)

                right_shoulder = [landmarks[mp_pose.PoseLandmark.RIGHT_SHOULDER.value].x,landmarks[mp_pose.PoseLandmark.RIGHT_SHOULDER.value].y]
                right_elbow = [landmarks[mp_pose.PoseLandmark.RIGHT_ELBOW.value].x,landmarks[mp_pose.PoseLandmark.RIGHT_ELBOW.value].y]
                right_wrist = [landmarks[mp_pose.PoseLandmark.RIGHT_WRIST.value].x,landmarks[mp_pose.PoseLandmark.RIGHT_WRIST.value].y]
                right_elbow_angle = calculate_angle(right_shoulder, right_elbow, right_wrist)

                right_hip = [landmarks[mp_pose.PoseLandmark.RIGHT_HIP.value].x,landmarks[mp_pose.PoseLandmark.RIGHT_HIP.value].y]
                right_knee = [landmarks[mp_pose.PoseLandmark.RIGHT_KNEE.value].x,landmarks[mp_pose.PoseLandmark.RIGHT_KNEE.value].y]
                right_ankle = [landmarks[mp_pose.PoseLandmark.RIGHT_ANKLE.value].x,landmarks[mp_pose.PoseLandmark.RIGHT_ANKLE.value].y]
                right_knee_angle = calculate_angle(right_hip, right_knee, right_ankle)            

                left_hip = [landmarks[mp_pose.PoseLandmark.LEFT_HIP.value].x,landmarks[mp_pose.PoseLandmark.LEFT_HIP.value].y]
                left_knee = [landmarks[mp_pose.PoseLandmark.LEFT_KNEE.value].x,landmarks[mp_pose.PoseLandmark.LEFT_KNEE.value].y]
                left_ankle = [landmarks[mp_pose.PoseLandmark.LEFT_ANKLE.value].x,landmarks[mp_pose.PoseLandmark.LEFT_ANKLE.value].y]
                left_knee_angle = calculate_angle(left_hip, left_knee, left_ankle)   

                right_eye_inner = [landmarks[mp_pose.PoseLandmark.RIGHT_EYE_INNER.value].x,landmarks[mp_pose.PoseLandmark.RIGHT_EYE_INNER.value].y]
                right_eye = [landmarks[mp_pose.PoseLandmark.RIGHT_EYE.value].x,landmarks[mp_pose.PoseLandmark.RIGHT_EYE.value].y]
                right_eye_outer = [landmarks[mp_pose.PoseLandmark.RIGHT_EYE_OUTER.value].x,landmarks[mp_pose.PoseLandmark.RIGHT_EYE_OUTER.value].y]
                right_eye_angle = calculate_angle(right_eye_inner, right_eye, right_eye_outer)

                left_eye_inner = [landmarks[mp_pose.PoseLandmark.LEFT_EYE_INNER.value].x,landmarks[mp_pose.PoseLandmark.LEFT_EYE_INNER.value].y]
                left_eye = [landmarks[mp_pose.PoseLandmark.LEFT_EYE.value].x,landmarks[mp_pose.PoseLandmark.LEFT_EYE.value].y]
                left_eye_outer = [landmarks[mp_pose.PoseLandmark.LEFT_EYE_OUTER.value].x,landmarks[mp_pose.PoseLandmark.LEFT_EYE_OUTER.value].y]
                left_eye_angle = calculate_angle(left_eye_inner, left_eye, left_eye_outer)

                back_turn_calc = distance(landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value].x, landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value].y,
                                landmarks[mp_pose.PoseLandmark.RIGHT_SHOULDER.value].x, landmarks[mp_pose.PoseLandmark.RIGHT_SHOULDER.value].y)

                if(back_turn_calc <= 0.1):     
                    image = Image.fromarray(image)
                    draw = ImageDraw.Draw(image)
                    draw.text((280, 30), "뒤집기 감지", font=ImageFont.truetype("./fonts/ONE Mobile Regular.ttf", 30), fill=(0,0,255))
                    image = np.array(image)
                    back_over_check_flag = 0
                else :
                    back_over_check_flag = 1     
                
                cv2.putText(image, str(left_elbow_angle), 
                                tuple(np.multiply(left_elbow, [603,1080]).astype(int)), 
                                cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2, cv2.LINE_AA)
                cv2.putText(image, str(right_elbow_angle), 
                                tuple(np.multiply(right_elbow, [603,1080]).astype(int)), 
                                cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2, cv2.LINE_AA)
                cv2.putText(image, str(right_knee_angle), 
                                tuple(np.multiply(right_knee, [603,1080]).astype(int)), 
                                cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2, cv2.LINE_AA)
                cv2.putText(image, str(left_knee_angle), 
                                tuple(np.multiply(left_knee, [603,1080]).astype(int)), 
                                cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2, cv2.LINE_AA)
                cv2.putText(image, str(right_eye_angle), 
                                tuple(np.multiply(right_eye, [603,1080]).astype(int)), 
                                cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2, cv2.LINE_AA)
                cv2.putText(image, str(left_eye_angle), 
                                tuple(np.multiply(left_eye, [603,1080]).astype(int)), 
                                cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2, cv2.LINE_AA)                   
    #             if(time<200):
    #                 time = time +1
    #             elif(time>=200):
    #                 left_elbow_list.append(left_elbow_angle)
    #                 right_elbow_list.append(right_elbow_angle)
    #                 left_knee_list.append(left_knee_angle)
    #                 right_knee_list.append(right_knee_angle)
    #                 time = 0


                # if (left_elbow_angle > 160):
                #         stage = "down"
                # if left_elbow_angle < 30 and stage =='down':
                #         stage="up"
                #         counter +=1

                # cv2.rectangle(image, (0,0), (225,73), (245,117,16), -1)


                # cv2.putText(image, 'REPS', (15,12), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,0,0), 1, cv2.LINE_AA)
                # cv2.putText(image, str(counter), (10,60), cv2.FONT_HERSHEY_SIMPLEX, 2, (255,255,255), 2, cv2.LINE_AA)


                # cv2.putText(image, 'STAGE', (65,12), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,0,0), 1, cv2.LINE_AA)
                # cv2.putText(image, stage,  (60,60),  cv2.FONT_HERSHEY_SIMPLEX, 2, (255,255,255), 2, cv2.LINE_AA)



            except:
                pass

            mp_drawing.draw_landmarks(image, results.pose_landmarks, mp_pose.POSE_CONNECTIONS,
                    mp_drawing.DrawingSpec(color=(245,117,66), thickness=2, circle_radius=2), 
                    mp_drawing.DrawingSpec(color=(245,66,230), thickness=2, circle_radius=2) )

광주인공지능학원에서 배우지 못한 쓰레딩을 도전해보려한다.

광주인공지능학원에서도 안드로이드 관련 쓰레드는 배우지만 파이썬 관련 쓰레딩은 개인 공부가 필요하다

1. 프로세스(Process)

프로세스에 대한 설명을 먼저 위키백과에서 어떻게 하고 있는지 확인해볼게요.

프로세스(process)는 컴퓨터에서 연속적으로 실행되고 있는 컴퓨터 프로그램을 말한다. 종종 스케줄링의 대상이 되는 작업(task)이라는 용어와 거의 같은 의미로 쓰인다. 여러 개의 프로세서를 사용하는 것을 멀티프로세싱이라고 하며 같은 시간에 여러개의 프로그램을 띄우는 시분할 방식을 멀티태스킹이라고 한다. 프로세스 관리는 운영 체제의 중요한 부분이 되었다.

위의 설명처럼 프로세스란, 실행되고 있는, 실행중인 프로그램을 말합니다.

프로그램은 실행이 되기 전의 명령어와 데이터의 묶음인데, 이러한 정적인 요소인 프로그램이 실행 중에 있을때 그것들을 우리는 프로세스라고 말합니다.

다시 말해서, 하드디스크에 저장되어 있는 명령어와 데이터의 묶음 자체는 프로그램이며

프로세스는 그러한 프로그램을 구동하여(실행하여), 프로그램 자체와 프로그램의 상태가 메모리 상에서 실행되는 작업단위를 말합니다.

예를 들어서, 컴퓨터에 A라는 프로그램이 존재합니다. A라는 것을 실행시키기 전에는 단순히 프로그램으로써 존재합니다. 헌데 A를 실행시켜서, 현재 실행되고 있는 A를 프로세스라고 합니다.

 

일반적으로 CPU는 한번에 하나의 프로세스만 관리할 수 있습니다.

그런데 우리는 한번에 여러개의 프로그램을 실행하고 있죠? 즉, 우리는 한번에 여러개의 프로세스를 사용하고 있습니다.

CPU는 하나의 프로세스만 관리가 가능한데, 이점을 극복하고 우리가 사용하듯이 여러개의 프로세스가 동시에 실행되도록 하는 것이 멀티태스킹입니다.

이에 대한 자세한 설명은 밑에서 드리겠지만 간략히 말씀드리면, 멀티태스킹은 엄밀히 말해 한번에 다수의 프로세스를 실행하고 있는 것이 아니고 사용자로 하여금 다수의 프로세스가 동시에 실행되는 것 '처럼' 보이게 만드는 것입니다.

즉, CPU가 빠른 시간동안 각각의 프로세스를 순차적으로 실행하는 것 입니다.

예를 들어 A 프로세스를 몇 초간, 그리고 B 프로세스를 몇 초간, 다시 A 프로세스, 다시 B 프로세스, ... 이렇게 반복해가며 다수의 프로세스를 관리하기 때문에 사용자는 한번에 다수의 프로세스가 실행되고 있는 것 처럼 보이는 것입니다.


1-2. 프로세스의 상태 (Process state)

일반적으로 프로세스의 상태는 커널에 의해 관리됩니다.

프로세스의 상태가 PCB에 저장되어 있는데 위에서 말한 것과 같이 PCB는 일반적인 사용자가 접근하지 못하는 영역에 저장되어 있습니다. 이때 커널 스택 영역은 편리하면서도 보호받는 위치이기 때문에 주로 이용됩니다.

 

프로세스의 상태로는 생성(create), 실행(running), 준비(ready), 대기(waiting), 종료(terminated) 상태가 있습니다.

그림에서 다섯개의 파란색 동그라미가 각각 프로세스의 상태입니다. (new는 생성, create와 같은 의미입니다.)

생성(create or new) 상태란, 프로세스 자체는 생성되었지만 아직 프로그램이 메모리에 적재되지 않은 상태를 말합니다.

준비(ready) 상태란, 실행된 프로세스가 메모리에 적재되고 CPU를 할당 받기 위해서 준비중인 상태입니다.

실행(running) 상태란, 프로세스가 CPU를 할당받아서 명령어를 실행하고 있는 상태입니다.

대기(waiting or Block) 상태란, 실행상태에 있던 프로세스가 급작스런 이벤트에 의해 실행을 일시적으로 멈춘 상태를 말합니다.

종료(terminated) 상태란, 프로세스의 실행이 모두 정상적으로 끝나서 종료된 상태를 말합니다.

 

위의 그림에서 볼 수 있듯이 각각의 상태는 특정 이벤트에 의해 변화됩니다.

우리는 이러한 것을 프로세스의 상태 전이라고 말합니다.

각각의 프로세스의 상태 전이에 대한 설명은 아래와 같습니다.

 

admitted: 생성된 프로세스가 승인을 받아서 실행이 됩니다.

scheduler dispatch: 보통 dispatch라고도 말하며, 준비상태에 있던 프로세스가 CPU를 할당받아서 실행되는 것입니다.

interrupt: 실행 중이던 프로세스가 특정 이벤트에 의해서 다시 준비상태로 넘어가는 것입니다. 프로세스가 할당된 시간에 모든 명령을 실행하지 못하여 넘어가는 Time out 등이 있습니다.

I/O or event wait: CPU가 프로세스를 실행 중에 있을 때 급작스런 이벤트에 의해서 CPU가 다른 프로세스를 할당하게 될때 현재 실행중인 프로세스는 대기상태로 넘어가는데 이러한 상태전이를 말합니다.

I/O or event completion: 급작스런 이벤트에 의한 CPU할당을 받는 프로세스의 실행이 끝나면 대기상태에 있던 프로세스는 다시 준비상태로 넘어가게 됩니다. 이러한 상태 전이를 말합니다.

exit: 프로세스의 모든 명령이 실행되고 종료되는 상황을 말합니다.


2. 스레드(Thread)

스레드가 무엇일까요?

위키백과에는 아래와 같은 설명으로 나와있습니다.

스레드(thread)는 어떠한 프로그램 내에서, 특히 프로세스 내에서 실행되는 흐름의 단위를 말한다. 일반적으로 한 프로그램은 하나의 스레드를 가지고 있지만, 프로그램 환경에 따라 둘 이상의 스레드를 동시에 실행할 수 있다. 이러한 실행 방식을 멀티스레드(multithread)라고한다.

위에서 우리는 프로세스에 대해서 알아보았습니다.

실행 중인 프로그램을 프로세스라고 했는데, 스레드는 그러한 프로세스 내부에서 실행되는 흐름의 단위 입니다.

즉 프로세스의 내부에 있는 개체를 말합니다. 하나의 프로세스에는 최소 하나이상의 스레드가 존재합니다.

하나의 스레드가 있을 때는 단일 스레드라고 말하며 두개 이상의 스레드가 존재하면 멀티스레드, 다중스레드라고 말합니다.

멀티 프로세싱(Multi-processing)

멀티 프로세싱은 한마디로 말해서 '두개 이상, 다수의 프로세서가 협력적으로 작업을 동시에 처리하는 것' 입니다.

위에서 설명한 '프로세스'가 아닌 '프로세서'를 말하는 것에 혼동되면 안됩니다.

프로세서는 대략적으로 CPU라고 생각하시면 됩니다.

아래 사진을 보면 더 이해하기 쉬울 것 입니다.

 

멀티 프로그래밍(Multi-programming)

멀티 프로그래밍의 개념은 위에서 잠깐 언급한 멀티테스킹과 혼동될 수 있으니 잘 구분하길 바랍니다.

멀티 프로그래밍이란, 특정 프로세스 A에 대해서 프로세서가 작업을 처리할때 낭비되는 시간동안 다른 프로세스를 처리하도록 하는 것 입니다.

예를 들어 A라는 프로세스를 처리중에 있을때 입출력 이벤트가 발생했는데 프로세서가 입출력 이벤트에 대한 응답을 위해 무작정 대기하고 있다면 프로세서의 자원을 낭비하는 결과를 초래합니다. 프로세서, CPU는 한번에 하나의 프로세스만 처리하도록 되어있기 때문에 A 프로세스에 대한 입출력 이벤트에 대한 응답을 대기하는 동안 아무일도 하지 않기 때문이죠.

멀티 프로그래밍은 이렇게 낭비되는 시간동안 프로세서가 다른 프로세스를 수행할 수 있도록 하는 것 입니다.


멀티 테스킹(Multi-tasking)

멀티 테스킹이란 다수의 Task(프로세스보다 보다 확장된 개념이라고 생각하시면 됩니다.)를 운영체제의 스케줄링에 의해 번갈아 가면서 수행하는 것 입니다.

프로세서가 각각의 Task를 조금씩 자주 번갈아가면서 처리하기 때문에 사용자는 마치 동시에 여러 Task가 수행되는 것처럼 보게 됩니다.

 

위에서 말한 멀티프로그래밍과의 차이점으로는,

멀티프로그래밍은 프로세서의 자원이 낭비되는 것을 최소화하기 위한 것이며

멀티테스킹은 일정하게 정해진 시간동안 번갈아가면서 각각의 Task를 처리하는 것입니다.

 

프로세스와 스레드의 차이점

위에서 프로세스와 스레드에 대해서 이해하셨다면 그 차이점에 대해서도 어느정도 느낌이 오셨을 겁니다.

프로세스가 실행될때 운영체제로 부터 어떤 것들을 할당받을까요?

프로세스는 자신을 실행할 프로세서를 할당받으며 필요한 메모리공간과 데이터등을 할당받습니다.

그리고 스레드란 이러한 프로세스 안에서 실행되는 흐름의 단위로써, 프로세스 안에서의 주소나 데이터를 스레드 간에 공유하면서 실행됩니다.

스레드가 존재함으로써 데이터와 같은 자원을 메모리에 할당하는 동작이 줄어들어서 자원을 효율적으로 관리하고 운영할 수 있습니다.

아래는 위의 설명을 그림으로 표현한 것이다.


광주인공지능학원에서 팀원들과 회의결과 우리는 멀티 쓰레드를 선택하기로 했다.

문제는 광주인공지능학원에서 프로젝트를 하던 중 플라스크와 멀티쓰레드가 동시에 돌아가지 않는다는걸 알게 되었다.

광주인공지능학원에서 8시간만에 멀티쓰레드의 해결법을 찾았다.

플라스크 자체를 함수화해 플라스크역시 쓰레딩을 돌려주는 것이었다.

그런데 쓰레딩이 늘어날 수록 컴퓨팅 파워가 많이 필요하는 것도 사실이다 다행디도 광주인공지능학원 컴퓨팅파워가 좋아 잘 돌아가지만.. 내 본컴에서는 안돌아간다.

"스마트인재개발원에서 진행된 수업내용입니다"

https://www.smhrd.or.kr/

 

스마트인재개발원

4차산업혁명시대를 선도하는 빅데이터, 인공지능, 사물인터넷 전문 '0원' 취업연계교육기관

www.smhrd.or.kr