CS

동기, 비동기, λΈ”λ‘œν‚Ή, λ…ΌλΈ”λ‘œν‚Ή (cpp)

moaoh 2024. 12. 14. 12:58

동기와 비동기

동기

μž‘μ—…μ„ 순차적으둜 μ§„ν–‰ν•˜λŠ” 방식

ν•˜λ‚˜μ˜ μž‘μ—…μ΄ 끝날 λ•ŒκΉŒμ§€ λ‹€μŒ μž‘μ—…μ€ μ‹€ν–‰λ˜μ§€ μ•Šκ³  κΈ°λ‹€λ¦°λ‹€.

 

μ˜ˆμ‹œ : μž‘μ—… A -> μž‘μ—… B -> μž‘μ—… C (Aκ°€ 끝날 λ•ŒκΉŒμ§€ B, CλŠ” μ‹€ν–‰λ˜μ§€ μ•ŠμŒ)

비동기

μž‘μ—…μ„ 기닀리지 μ•Šκ³  λ™μ‹œμ— μ§„ν–‰

μž‘μ—…μ„ μš”μ²­ν•˜λ©΄ κ·Έ μž‘μ—…μ΄ μ™„λ£Œλ  λ•ŒκΉŒμ§€ 기닀리지 μ•Šκ³ , λ‹€λ₯Έ μž‘μ—…μ„ 계속 μ§„ν–‰

 

μ˜ˆμ‹œ : μž‘μ—… A -> μž‘μ—… B -> μž‘μ—… C (Aκ°€ μ§„ν–‰λ˜λŠ” λ™μ•ˆ B와 C도 λ™μ‹œμ— 싀행될 수 있음)


λΈ”λ‘œν‚Ήκ³Ό λ…ΌλΈ”λ‘œν‚Ή

λΈ”λ‘œν‚Ή

μž‘μ—…μ΄ μ™„λ£Œλ  λ•ŒκΉŒμ§€ μ œμ–΄κΆŒμ„ λ°˜ν™˜ν•˜μ§€ μ•ŠλŠ” 방식

μ–΄λ– ν•œ μž‘μ—…μ΄ λλ‚ λ•ŒκΉŒμ§€ κΈ°λ‹€λ Έλ‹€κ°€ μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” 경우

 

μ˜ˆμ‹œ : μž‘μ—… A -> λŒ€κΈ° -> μž‘μ—… B -> λŒ€κΈ° -> μž‘μ—… C (각 μž‘μ—…μ΄ 끝날 λ•ŒκΉŒμ§€ λŒ€κΈ°)

λ…ΌλΈ”λ‘œν‚Ή

μž‘μ—…μ΄ μ§„ν–‰λ˜λŠ” λ™μ•ˆμ—λ„ μ œμ–΄κΆŒμ„ λ°˜ν™˜ν•˜κ³  λ‹€λ₯Έ μž‘μ—…μ„ 계속 μ§„ν–‰

λ‹€λ₯Έ μž‘μ—…κ³Ό 상관없이 μžμ‹ μ˜ μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” 것

 

μ˜ˆμ‹œ : μž‘μ—… A μ§„ν–‰ 쀑 -> μž‘μ—… B μ‹œμž‘ -> μž‘μ—… C μ‹œμž‘ (각 μž‘μ—…μ€ λ…λ¦½μ μœΌλ‘œ μ‹€ν–‰)


즉, 동기와 λΉ„λ™κΈ°λŠ” μž‘μ—…μ˜ μˆœμ„œλ₯Ό 순차적으둜 할것이냐, μˆœμ°¨μ μ΄μ§€μ•Šκ²Œ μ§„ν–‰ν•  것이냐λ₯Ό μ΄μ•ΌκΈ°ν•˜λŠ”κ²ƒμ΄κ³ , λΈ”λ‘œν‚Ή λ…ΌλΈ”λ‘œν‚Ήμ€ μ–΄λ–€ν•œ μž‘μ—…μ„ μ§„ν–‰ν•΄μ•Όν• λ•Œ, μž‘μ—…μ— λŒ€ν•΄ μ œμ–΄κΆŒμ„ κ°€μ§€κ³  ν•Έλ“€λ§ν•˜λŠ”κ²ƒμ„ μ΄μ•ΌκΈ°ν•œλ‹€.

 

동기와 비동기 : μž‘μ—…μ˜ μˆœμ„œ

λΈ”λ‘œν‚Ήκ³Ό λ…ΌλΈ”λ‘œν‚Ή : μ œμ–΄κΆŒμ˜ λ°˜ν™˜μ—¬λΆ€


μ½”λ“œλ₯Ό ν†΅ν•œ μ˜ˆμ‹œ (cpp)

동기 λΈ”λ‘œν‚Ή

void print(const std::string& message) {
	std::cout << "[start] :" << message << std::endl;
	std::this_thread::sleep_for(std::chrono::seconds(2)); // 2s
	std::cout << "[end] :" << message << std::endl;
}

...
	print("hello!");
	print("world!");
...
[start] :hello!
[start] :world!
[end] :hello!
[end] :world!

동기 : ν•¨μˆ˜μ˜ 호좜이 λλ‚ λ•ŒκΉŒμ§€ λ‹€μŒμ½”λ“œλŠ” μ‹€ν–‰λ˜μ§€μ•ŠλŠ”λ‹€.

λΈ”λ‘œν‚Ή : 호좜된 ν•¨μˆ˜κ°€ μ‹€ν–‰λ˜λŠ” λ™μ•ˆ μ œμ–΄κΆŒμ„ λ°˜ν™˜λ°›μ§€ λͺ»ν•œλ‹€.

비동기 λ…ΌλΈ”λ‘œν‚Ή

void print(const std::string& message) {
	std::cout << "[start] :" << message << std::endl;
	std::this_thread::sleep_for(std::chrono::seconds(2)); // 2s
	std::cout << "[end] :" << message << std::endl;
}

...
	std::thread t1(print, "hello!");
	std::thread t2(print, "world!");
	
	t1.detach();
	t2.detach();
	std::cout << "Main thread start!" << std::endl;

	std::this_thread::sleep_for(std::chrono::seconds(3)); // 3s

	std::cout << "Main thread end!" << std::endl;
...
[start] :hello!
[end] :hello!
Main thread start!
[start] :world!
[end] :world!
Main thread end!

비동기 : threadλ₯Ό λ°”νƒ•μœΌλ‘œ λ³„λ„μ˜ μŠ€λ ˆλ“œλ₯Ό 톡해 λ™μž‘ν•˜μ˜€κΈ°λ•Œλ¬Έμ— t1 이 μ‹€ν–‰λ˜λŠ” λ™μ•ˆ t2 도 λ™μ‹œμ— 싀행이 이루어진닀.

λ…ΌλΈ”λ‘œν‚Ή : detachλ₯Ό μ‚¬μš©ν•˜μ—¬ 메인 μŠ€λ ˆλ“œμ™€ λ…λ¦½μ μœΌλ‘œ 싀행이 λœλ‹€.

동기 λ…ΌλΈ”λ‘œν‚Ή

μ½”λ“œλ₯Ό 톡해 ν‘œν˜„ν•˜κΈ°μ• λ§€ν•˜λ‹€.

동기: μž‘μ—…λ“€μ΄ 순차적으둜 μ§„ν–‰λ˜λ―€λ‘œ, 각 μž‘μ—…μ€ 이전 μž‘μ—…μ΄ μ™„λ£Œλ  λ•ŒκΉŒμ§€ κΈ°λ‹€λ¦½λ‹ˆλ‹€.

λ…ΌλΈ”λ‘œν‚Ή: μž‘μ—…μ΄ μ™„λ£Œλ  λ•ŒκΉŒμ§€ 기닀리지 μ•Šκ³ , λ‹€λ₯Έ μž‘μ—…μ„ μ§„ν–‰ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

 

μœ„μ™€ 같은 νŠΉμ§•μ„ κ°€μ§€κ³ μžˆκΈ°λ•Œλ¬Έμ— 두 κ°œλ…μ΄ 본질적으둜 μƒλ°˜λœ 성격을 κ°€μ§„λ‹€.

λ™κΈ°λŠ” μ½”λ“œμ˜ 진행을 순차적으둜 ν•œλ‹€λŠ” 큰 틀을 κ°€μ§€κ³ μžˆκΈ°λ•Œλ¬Έμ— λ…ΌλΈ”λ‘œν‚Ήμ„ ν•œλ‹€κ³  해도 λ™κΈ°λ‘œ 인해 λ¬»ν˜€λ²„λ¦°λ‹€

 

비동기 λΈ”λ‘œν‚Ή

void print(const std::string& message) {
	std::cout << "[start] :" << message << std::endl;
	std::this_thread::sleep_for(std::chrono::seconds(2)); // 2s
	std::cout << "[end] :" << message << std::endl;
}

...
	std::thread t1(print, "hello!");
	std::thread t2(print, "world!");
	
	t1.join();
	t2.join();
	std::cout << "Main thread start!" << std::endl;

	std::this_thread::sleep_for(std::chrono::seconds(3)); // 3s

	std::cout << "Main thread end!" << std::endl;
...
[start] :hello!
[end] :hello!
[start] :world!
[end] :world!
Main thread start!
Main thread end!

비동기 : threadλ₯Ό λ°”νƒ•μœΌλ‘œ λ³„λ„μ˜ μŠ€λ ˆλ“œλ₯Ό 톡해 λ™μž‘ν•˜μ˜€κΈ°λ•Œλ¬Έμ— t1 이 μ‹€ν–‰λ˜λŠ” λ™μ•ˆ t2 도 λ™μ‹œμ— 싀행이 이루어진닀.

λΈ”λ‘œν‚Ή: join 으둜 μΈν•˜μ—¬ λΈ”λ‘œν‚Ήμ²˜λ¦¬κ°€ λ˜μ–΄ join threadκ°€ λ§ˆλ¬΄λ¦¬κ°€ λ˜κΈ°μ „κΉŒμ§€ λ„˜μ–΄κ°ˆ 수 μ—†λ‹€.