๐Ÿ ์Šค๋ ˆ๋“œ

ํŒ”๋ฆฌ๋™ยท2021๋…„ 8์›” 6์ผ
0

์Šค๋ ˆ๋“œ์˜ ๊ฐœ๋…๊ณผ ํŒŒ์ด์ฌ์—์„œ ์Šค๋ ˆ๋“œ ์‚ฌ์šฉ๋ฐ ๋ฌธ์ œ์ ์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์ž

๐Ÿงถ What is ์Šค๋ ˆ๋“œ?

์Šค๋ ˆ๋“œ(thread)๋Š” ์–ด๋– ํ•œ ํ”„๋กœ๊ทธ๋žจ ๋‚ด์—์„œ, ํŠนํžˆ ํ”„๋กœ์„ธ์Šค ๋‚ด์—์„œ ์‹คํ–‰๋˜๋Š” ํ๋ฆ„์˜ ๋‹จ์œ„๋ฅผ ๋งํ•œ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ํ•œ ํ”„๋กœ๊ทธ๋žจ์€ ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์ง€๋งŒ, ํ”„๋กœ๊ทธ๋žจ ํ™˜๊ฒฝ์— ๋”ฐ๋ผ ๋‘˜ ์ด์ƒ์˜ ์Šค๋ ˆ๋“œ๋ฅผ ๋™์‹œ์— ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฌํ•œ ์‹คํ–‰ ๋ฐฉ์‹์„ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ(multithread)๋ผ๊ณ  ํ•œ๋‹ค.

์ถœ์ฒ˜:์œ„ํ‚ค๋ฐฑ๊ณผ ์Šค๋ ˆ๋“œ

์Šค๋ ˆ๋“œ์˜ ํŠน์ง•

  • ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค์— ์—ฌ๋Ÿฌ๊ฐœ์˜ ์Šค๋ ˆ๋“œ ์ƒ์„ฑ ๊ฐ€๋Šฅ
  • ์Šค๋ ˆ๋“œ๋“ค์€ ๋™์‹œ์— ์‹คํ–‰ ๊ฐ€๋Šฅ
  • ํ”„๋กœ์„ธ์Šค ์•ˆ์— ์žˆ์œผ๋ฏ€๋กœ,ํ”„๋กœ์„ธ์Šค์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ชจ๋‘ ์ ‘๊ทผ ๊ฐ€๋Šฅ

์Šค๋ ˆ๋“œ๋Š” ๊ฐ๊ธฐ ์‹คํ–‰์ด ๊ฐ€๋Šฅํ•œ stack์ด ์กด์žฌํ•œ๋‹ค.

๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ

  • ์†Œํ”„ํŠธ์›จ์›Œ์˜ ๋ณ‘ํ–‰ ์ž‘์—… ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

์Šค๋ ˆ๋“œ์˜ ์žฅ์ 

  • IPC๊ธฐ๋ฒ•๊ณผ ๊ฐ™์ด ํ”„๋กœ์„ธ์Šค๊ฐ„ ์ž์› ๊ณต์œ ๋ฅผ ์œ„ํ•ด ๋ฒˆ๊ฑฐ๋กœ์šด ์ž‘์—…์ด ํ•„์š”์—†๋‹ค. ->>contextswitcing์— ๋ฆฌ์†Œ์Šค๊ฐ€ ์ ๊ฒŒ๋“ ๋‹ค.
  • ํ”„๋กœ์„ธ์Šค ์•ˆ์— ์žˆ์œผ๋ฏ€๋กœ, ํ”„๋กœ์„ธ์Šค์˜ ๋ฐ์ดํ„ฐ์— ๋ชจ๋‘ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•˜๋‹ค.

์Šค๋ ˆ๋“œ์˜ ๋‹จ์ 

  • ์Šค๋ ˆ๋“œ ์ค‘ ํ•œ ์Šค๋ ˆ๋“œ๋งŒ ๋ฌธ์ œ๊ฐ€ ์žˆ์–ด๋„, ์ „์ฒด ํ”„๋กœ์„ธ์Šค๊ฐ€ ์˜ํ–ฅ์„ ๋ฐ›์Œ -> ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค ์ž์‹ ์Šค๋ ˆ๋“œ๋“ค์ด ๋ถ€๋ชจ ํ”„๋กœ์„ธ์Šค์˜ ์ž์›์„ ๊ณต์œ ํ•˜๊ธฐ๋•Œ๋ฌธ

  • ์Šค๋ ˆ๋“œ๋ฅผ ๋งŽ์ด์ƒ์„ฑํ•˜๋ฉด, Context Switching์ด ๋งŽ์ด ์ผ์–ด๋‚˜, ์„ฑ๋Šฅ ์ €ํ•˜ -->> ์Šค๋ ˆ๋“œ๋ฅผ ๋งŽ์ด ์ƒ์„ฑํ•˜๋ฉด, ๋ชจ๋“  ์Šค๋ ˆ๋“œ๋ฅผ ์Šค์ผ€์ฅด๋งํ•ด์•ผ ํ•˜๋ฏ€๋กœ, Cintext Switching์ด ๋นˆ๋ฒˆํ•  ์ˆ˜ ๋ฐ–์— ์—†์Œ

์Šค๋ ˆ๋“œ VS ํ”„๋กœ์„ธ์Šค

  • ํ”„๋กœ์„ธ์Šค๋Š” ๋…๋ฆฝ์ , ์Šค๋ ˆ๋“œ๋Š” ํ”„๋กœ์„ธ์Šค์˜ ์„œ๋ธŒ์…‹
  • ํ”„๋กœ์„ธ์Šจ ๊ฐ๊ฐ ๋…๋ฆฝ์ ์ธ ์ž์›์„ ๊ฐ€์ง, ์Šค๋ ˆ๋“œ๋Š” ํ”„๋กœ์„ธ์Šค ์ž์›๊ณต์œ 
  • ํ”„๋กœ์„ธ์Šค๋Š” ์ž์‹ ๋งŒ์˜ ์ฃผ์†Œ์˜์—ญ์„ ๊ฐ€์ง, ์Šค๋ ˆ๋“œ๋Š” ์ฃผ์†Œ์˜์—ญ ๊ณต์œ 
  • ํ”„๋กœ์„ธ์Šค๊ฐ„์—๋Š” IPC ๊ธฐ๋ฒ•์œผ๋กœ ํ†ต์‹ ํ•ด์•ผํ•จ, ์Šค๋ ˆ๋“œ๋Š” ํ•„์š” ์—†์Œ

๐Ÿ˜‰ ์Šค๋ ˆ๋“œ์˜ ๋ฌธ์ œ์ 

  • ํŒŒ์ด์ฌ์—์„œ ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๋ฌธ์ œ์ ์„ ์•Œ์•„๋ณด์ž

ํŒŒ์ด์ฌ์€ ์‹ฑ๊ธ€์Šค๋ ˆ๋“œ๋‹ค!

  • ์Šค๋ ˆ๋“œ์˜ ์žฅ์  ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๋กœ ์ž‘์—…์˜ ์†๋„๋ฅผ ํ–ฅ์ƒ์ธ๋ฐ ์•„์‰ฝ๊ฒŒ๋„ ํŒŒ์ด์ฌ์€ ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋”ฉ์„ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค.

    ์™œ?

  • ๋ฐ”๋กœ GIL(Global Interpreter Lock) ๋•Œ๋ฌธ์ด๋‹ค.

    GIL์ด ๋ญ”๋ฐ?

  • GIL์ด๋ž€ Global Interpreter Lock์˜ ์•ฝ์ž๋กœ ํŒŒ์ด์ฌ ์ธํ„ฐํ”„๋ฆฌํ„ฐ๊ฐ€ ํ•œ ์Šค๋ ˆ๋“œ๋งŒ ํ•˜๋‚˜์˜ ๋ฐ”์ดํŠธ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š” Lock์ž…๋‹ˆ๋‹ค.
    ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ์— ๋ชจ๋“  ์ž์›์„ ํ—ˆ๋ฝํ•˜๊ณ  ๊ทธ ํ›„์—๋Š” Lock์„ ๊ฑธ์–ด ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๋Š” ์‹คํ–‰ํ•  ์ˆ˜ ์—†๊ฒŒ ๋ง‰์•„๋ฒ„๋ฆฌ๋Š” ๊ฒƒ์ด์ฃ .
    ์ถœ์ฒ˜

    GIL์€ ์™œ ์ƒ๊ธด๊ฑฐ์•ผ?

  • GIL์€ ์ฒ˜์Œ ํŒŒ์ด์ฌ์— ์“ฐ๋ ˆ๋“œ ๊ตฌํ˜„์ด ๋“ค์–ด๊ฐˆ ๋•Œ ๊ฐ™์ด ์ƒ๊ธด ์ดํ›„๋กœ, ์ง€๊ธˆ๊นŒ์ง€ ๊ณ„์† ๋‚ด๋ ค์˜ค๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํŒŒ์ด์ฌ ๊ตฌํ˜„์€ ์ƒ๋‹น ๋ถ€๋ถ„์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ „์—ญ ๋ณ€์ˆ˜์— ์˜์กดํ•˜๊ณ  ์žˆ๊ณ , ์—ฌ๊ธฐ ์ €๊ธฐ ๊ฐ์ฒด ๊ตฌ์กฐ์— ๋”ฐ๋ผ์„œ ์ฐธ์กฐ๋ฅผ ๋”ฐ๋ผ์„œ ๋งˆ๊ตฌ ์ ‘๊ทผ์„ ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ๋™์‹œ์— ์“ฐ๋ ˆ๋“œ๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ ๋Œ์•„๊ฐˆ ๋•Œ ์‹ฌ๊ฐํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ, ํŒŒ์ด์ฌ์€ ์ดˆ์ฐฝ๊ธฐ๋ถ€ํ„ฐ ํŒŒ์ด์ฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ฝ”๋“œ๊ฐ€ ๋Œ์•„๊ฐ€๋Š” ์ค‘์—๋Š” ์ „์—ญ์ ์ธ ๋ฝ(GIL)์„ ๊ฑธ์–ด์„œ ๋™์‹œ์—๋Š” ์ ˆ๋Œ€๋กœ ๊ฐ™์ด ๋ชป ๋Œ์•„๊ฐ€๋„๋ก ํ•ด์„œ ํ•ด๊ฒฐํ•˜์˜€์Šต๋‹ˆ๋‹ค.์ถœ์ฒ˜

    ์‰ฝ๊ฒŒ ์„ค๋ช…ํ•ด๋ณด๋ฉด

    ์ถœ์ฒ˜
  • ์—ฌ๋Ÿฌ๊ฐœ์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ณ‘๋ ฌ๋กœ ์‹คํ–‰๋˜๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ Context Switching์„ ๋ฐ˜๋ณตํ•˜๋ฉด์„œ ์ˆœ์ฐจ์ ์œผ๋กœ ์‹คํ–‰๋œ๋‹ค.

์˜ˆ์ œ ์ฝ”๋“œ๋ฅผ ํ†ตํ•œ ์„ค๋ช…

import time

if __name__ == "__main__":
    
    increased_num = 0

    start_time = time.time()
    for i in range(100000000):
        increased_num += 1

    print("--- %s seconds ---" % (time.time() - start_time))

    print("increased_num=",end=""), print(increased_num)
    print("end of main")
    
--- 8.507359981536865 seconds ---
increased_num=100000000
end of main
  • ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์ˆซ์ž๋ฅผ 1์”ฉ์ฆ๊ฐ€ ์‹œ์ผœ์„œ 1์–ต์œผ๋กœ ๋งŒ๋“œ๋Š” ์ฝ”๋“œ์ด๋‹ค. ์ž๊ทธ๋งˆ์น˜ 8.5์ดˆ๋‚˜ ๊ฑธ๋ ธ๋‹ค. ์ด์ œ ์Šค๋ ˆ๋“œ๋ฅผ ํ™œ์šฉํ•ด์„œ ์‹œ๊ฐ„์„ ๋‹จ์ถ• ์‹œ์ผœ๋ณด์ž
import threading
import time

shared_number = 0

def thread_1(number):
    global shared_number
    print("number = ",end=""), print(number)
    
    for i in range(number):
        shared_number += 1

def thread_2(number):
    global shared_number
    print("number = ",end=""), print(number)
    for i in range(number):
        shared_number += 1


if __name__ == "__main__":

    threads = [ ]

    start_time = time.time()
    t1 = threading.Thread( target= thread_1, args=(50000000,) )
    t1.start()
    threads.append(t1)

    t2 = threading.Thread( target= thread_2, args=(50000000,) )
    t2.start()
    threads.append(t2)


    for t in threads:
        t.join()

    print("--- %s seconds ---" % (time.time() - start_time))

    print("shared_number=",end=""), print(shared_number)
    print("end of main")
  • ๋‘๊ฐœ์˜ ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•ด์„œ ์‹คํ–‰์„ ํ•ด๋ณด์•˜๋‹ค.
    ๊ฒฐ๊ณผ๋Š”????
number = 50000000
number = 50000000
--- 7.301347017288208 seconds ---
shared_number=65657956
end of main
  • 1์ดˆ๋ฐ–์— ์•ˆ ์ค„์–ด๋“ค์—ˆ๋‹ค! ์•„๋‹ˆ 2๊ฐœ๋ฅผ ์ƒ์„ฑํ–ˆ์œผ๋ฉด ๋ฐ˜์œผ๋กœ ์ค„์–ด์•ผ์ง€ ์–ด๋–ป๊ฒŒ 1์ดˆ๋ฐ–์— ์•ˆ ์ค„์ง€!

์œ„์—์„œ ์„ค๋ช…ํ•œ๋Œ€๋กœ ๋ณ‘๋ ฌ๋กœ ์‹คํ–‰์„ ํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ์‹œ๊ฐ„์ด ๋ฐ˜์œผ๋กœ ์ค„์–ด๋“ค์ง€ ์•Š๋Š”๋‹ค.

๋˜ํ•˜๋‚˜์˜ ๋ฌธ์ œ์ 

number = 50000000
number = 50000000
--- 7.301347017288208 seconds ---
shared_number=65657956  ------>>>>>????????
end of main
  • ๋˜ ํ•˜๋‚˜์˜ ๋ฌธ์ œ์ ์€ shared-number๊ฐ€ 1์–ต์ด ์•„๋‹ˆ๋ผ 6500๋งŒ ๋ฐ–์— ์•ˆ๋œ๋‹ค๋Š”๊ฒƒ์ด๋‹ค!
    ์ด์œ ๋ฅผ ์„ค๋ช…ํ•ด๋ณด๊ฒ ๋‹ค.

์Šค๋ ˆ๋“œ๋Š” ํ”„๋กœ์„ธ์Šค์˜ ๋ฐ์ดํ„ฐ ์˜์—ญ์„ ๊ณต์œ ํ•œ๋‹ค.

  • ์ž์‹ ์Šค๋ ˆ๋“œ๋“ค์€ ๋ถ€๋ชจ ํ”„๋กœ์„ธ์Šค์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ณต์œ ํ•œ๋‹ค.
    ์Šค๋ ˆ๋“œ๋Š” ๊ฐ์ž ์Šคํ…์˜์—ญ๊ณผ ๋ ˆ์ง€์Šคํ„ฐ์˜์—ญ์„ ๊ฐ–๊ณ  ์žˆ๊ณ  ๋‚˜๋จธ์ง€ ์ž์›์„ ๊ณต์œ ํ•œ๋‹ค.

๋ฌธ์ œ๋Š” ์ž์›์„ ๊ณต์œ ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

  • ์œ„์— ์„ค๋ช…ํ•œ๋Œ€๋กœ ์Šค๋ ˆ๋“œ๋Š” ์ž์›์„ ๊ณต์œ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์•„๊นŒ ์ฝ”๋“œ์—์„œ ์ „์—ญ๋ณ€์ˆ˜ shared_number๋ฅผ ์Šค๋ ˆ๋“œ๋“ค๋ผ๋ฆฌ ๊ณต์œ ํ•œ๋‹ค ๊ทธ๋ž˜์„œ ์ˆซ์ž๊ฐ€ 1์–ต๊นŒ์ง€ ์•ˆ ๊ฐ€๊ณ  6500๋งŒ๊นŒ์ง€๋งŒ ์˜ฌ๋ฅธ๋‹ค.

???????????? ์ž์›์„ ๊ณต์œ ํ•˜๋Š”๋ฐ ์™œ ์ˆซ์ž๊ฐ€ 1์–ต๊นŒ์ง€ ์•ˆ๊ฐ€๋Š”๊ฑฐ์ง€?

์Šค๋ ˆ๋“œ๊ฐ€ ๋ณ‘๋ ฌ๋กœ ์‹คํ–‰๋˜๋Š” ๊ฒƒ๋„ ์•„๋‹Œ๋ฐ ์™œ ๊ณต์œ ๋ฅผ ํ–ˆ๋‹ค๊ณ  ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธฐ์ง€? ํŒŒ์ด์ฌ ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ ์•„๋ƒ???

  • ์ด ์งˆ๋ฌธ์ด ๋จธ๋ฆฌ์†์„ ๋– ๋‚˜์ง€ ์•Š์•˜๋‹ค ๋™๊ธฐํ™” ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธด๋‹ค๋Š” ๊ฑธ ์•Œ๊ฒ ๋Š”๋ฐ ์•„๋‹ˆ ํŒŒ์ด์ฌใ…‡์€ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ์‹คํ–‰ ๋˜๋Š”๊ฒŒ ์•„๋‹Œ๋ฐ ์™œ ๋™๊ธฐํ™” ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธธ๊นŒ ๊ถ๊ธˆํ–ˆ๋‹ค.

๋ฌธ์ œ๋Š” Context Switching

  • ์šฐ์„  ์ปดํ“จํ„ฐ๊ฐ€ ๋ณ€์ˆ˜์— 1๋”ํ•˜๋Š” ๊ณผ์ •์„ ์•Œ์•„๋ณด์ž
  1. shared_number๋Š” ๋ฉ”๋ชจ๋ฆฌ์— ์ ์žฌ ๋˜์–ด์žˆ๋Š”๋ฐ ์ผ๋‹จ ์ฝ๋Š”๋‹ค.
  2. ๋Žƒ์…ˆ์„ ํ•œ๋‹ค.
  3. ์ €์žฅ์„ ํ•œ๋‹ค.
  • ์ฆ‰ 1์„ ๋”ํ•˜๋ ค๋ฉด ์ฝ๊ณ  ๊ฒŒ์‚ฐํ•˜๊ณ  ์ €์žฅ์„ ํ•ด์•ผํ•œ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ ๋งŒ์•ฝ ๋ง์…ˆ๋งŒํ•˜๊ณ  ์ €์žฅํ•˜๊ธฐ์ „์— ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ์ด ์ผ์–ด๋‚œ๋‹ค๋ฉด???

์œ„ ๊ทธ๋ฆผ ์ฒ˜๋Ÿผ ์Šค๋ ˆ๋“œ1์ด ๋ง์…ˆ๋งŒ ํ•˜๊ณ  Contexting Switching์ด ์ผ์–ด๋‚˜๋ฉด ์Šค๋ ˆ๋“œ2 ์—์„œ shared_number๊ฐ€ ์Œ 0์ด ๊ตฌ๋‚˜ ํ•˜๊ณ  ์ฝ๊ณ  ๋ง์…ˆ์„ํ•˜๊ณ  ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅ์„ ํ•˜๋ ค๊ณ  ํ•˜๋Š”๋ฐ ๋˜ Contexting Switching์ด ์ผ์–ด๋‚˜๋ฉด???

๊ทธ๋ ‡๋‹ค! ๊ทธ๋ฆผ์„ ๋ณด๋ฉด ์Šค๋ ˆ๋“œ2์—์„œ ์Šค๋ ˆ๋“œ1๋กœ ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ์„ ํ•˜๋ฉด์„œ ์Šค๋ ˆ๋“œ 1์€ ์•„๊นŒ ์ผ„ํ…์ŠคํŠธ ์Šค์œ„์นญ ๋˜๊ธฐ์ „์— ๋ ˆ์ง€์Šคํ„ฐ๊ฐ’1์„์ฐธ๊ณ ํ•ด์„œ ๋ณ€์ˆ˜(shared_number)1์— ์ €์žฅํ•˜๊ณ  ๋‹ค์‹œ ์Šค๋ ˆ๋“œ2๋กœ ์ผ„ํ…์ŠคํŠธ ์Šค์œ„์นญํ•˜๋ฉด ์Šค๋ ˆ๋“œ2๋„ ์ง์ „์— ๋ ˆ์ง€์Šคํ„ฐ๊ฐ’1์„ ์ฐธ์กฐํ•ด์„œ ๋ณ€์ˆ˜(shared_number)์— 1์„ ์ €์žฅํ•œ๋‹ค

  • ์ด๋Ÿฐ ๊ณผ์ • ๋•Œ๋ฌธ์— ์•„๊นŒ ๋ณ€์ˆ˜๊ฐ€ 1์–ต๊นŒ์ง€ ์•ˆ๊ฐ€๊ณ  6500๋งŒ๊นŒ์ง€ ๊ฐ€๋Š” ๊ฒƒ์ด๋‹ค.

๋ฐ˜๋ณตํ•˜๋Š” ์ˆซ์ž๊ฐ€ ์ž‘์œผ๋ฉด?

์˜ˆ์ œ์—์„œ๋Š” 5์ฒœ๋งŒ์„ ๋ฐ˜๋ณตํ–ˆ์ง€๋งŒ ์ˆซ์ž๋ฅผ 5๋งŒ์œผ๋กœ ์ค„์ด๋ฉด 10๋งŒ์ด ๋œ๋‹ค

number = 50000
number = 50000
--- 0.009940862655639648 seconds ---
shared_number=100000
  • ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ์„ ํ•˜๊ธฐ์ „์— ์ด๋ฏธ ๊ฒŒ์‚ฐ์„ ์™„๋ฃŒํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

ํ•ด๊ฒฐ๋ฐฉ์•ˆ

mutex

๋ฎคํ…์Šค๋ž€ Lock์™€ ๊ฐ™์€ ๊ธฐ์ˆ ๋กœ ์ž„๊ณ„์˜์—ญ์„ ๊ฐ€์ง„ ์Šค๋ ˆ๋“œ๋“ค์˜ ์‹คํ–‰ ์‹œ๊ฐ„์ด ์„œ๋กœ ๊ฒน์น˜์ง€ ์•Š๊ฒŒ ๊ฐ๊ฐ ๋‹จ๋…์œผ๋กœ ์‹คํ–‰๋˜๊ฒŒ ํ•˜๋Š” ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ ๊ณต์œ  ๋ฆฌ์†Œ์Šค์— ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ์ ‘๊ทผ ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ์ƒํ˜ธ ๋ฐฐ์ œ ๋™์‹œ์„ฑ ์ œ์–ด ์ •์ฑ…์„ ๊ฐ•์ œํ•˜๊ธฐ ์œ„ํ•ด ์„ค๊ณ„ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
์ถœ์ฒ˜

  • ๋ฎคํ…์Šค๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ž„๊ณ„์ž์›์— ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฝ์„ ๊ฑธ์–ด๋‘๋Š” ๊ฒƒ์ด๋‹ค.
  for i in range(number):
        shared_number += 1
  • ์•„๊นŒ ์Šค๋ ˆ๋“œ ์ฝ”๋“œ์—์„œ ์ด ๋ฐ˜๋ณต๋ฌธ์ด ์ž„๊ณ„์˜์—ญ์ด๊ณ  shared_number += 1๊ฐ€ ์ž„๊ณ„ ์ž์›์ด๋‹ค.

lock

lock.acquire()
for i in range(number):
    shared_number += 1
lock.release()  
  • lock.acquire() ํ•จ์ˆ˜๋Š” ์ž„๊ณ„์˜์—ญ(๋ฐ˜๋ณต๋ฌธ)์— ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ๋“ค์–ด๊ฐ€๋ฉด ํ™• ์ž ๊ฐ€๋ฒ„๋ ค์„œ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ๋“ค์–ด์˜ค์ง€๋ฅผ ๋ชปํ•œ๋‹ค.

  • ์Šค๋ ˆ๋“œ1๋ฒˆ์˜ ์ž„๊ณ„์˜์—ญ(๋ฐ˜๋ณต๋ฌธ)์ด ๋๋‚˜๋ฉด ์Šค๋ ˆ๋“œ 2๋ฒˆ์˜ ๋ฐ˜๋ณต๋ฌธ์ด ์‹œ์ž‘๋˜๊ณ  ๋๋‚œ๋‹ค.

์ตœ์ข… ์ˆ˜์ •์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

import threading
import time

shared_number = 0
lock = threading.Lock()

def thread_1(number):
    global shared_number
    print("number = ",end=""), print(number)
    lock.acquire()
    print("1๋ฒˆ ์‹œ์ž‘")
    for i in range(number):
        shared_number += 1
    print(shared_number)
    print("1๋ฒˆ ๋")
    lock.release()    
    

def thread_2(number):
    global shared_number
    print("number = ",end=""), print(number)
    lock.acquire()
    print("2๋ฒˆ ์‹œ์ž‘")
    for i in range(number):
        shared_number += 1
    print("2๋ฒˆ ๋")    
    lock.release()

if __name__ == "__main__":

    threads = [ ]

    start_time = time.time()
    t1 = threading.Thread( target= thread_1, args=(50000000,) )
    t1.start()
    threads.append(t1)

    t2 = threading.Thread( target= thread_2, args=(50000000,) )
    t2.start()
    threads.append(t2)


    for t in threads:
        t.join()

    print("--- %s seconds ---" % (time.time() - start_time))

    print("shared_number=",end=""), print(shared_number)
    print("end of main")
    
number = 50000000
number = 50000000
1๋ฒˆ ์‹œ์ž‘
1๋ฒˆ ๋
2๋ฒˆ ์‹œ์ž‘
2๋ฒˆ ๋
--- 7.250640869140625 seconds ---
shared_number=100000000
end of main   
profile
๋ฐฐ์›€์˜ ๊ธฐ๋ก

0๊ฐœ์˜ ๋Œ“๊ธ€