파이썬 스터디 15장
  C/C++ 연동

     Ahn Seong Hyun
OS 모듈

   현재 디렉토리 출력

import os;
print(os.getcwd())



C:UsersAhnSeongHyunDocumentseclipseworkspacepython_testsource



   디렉토리 변경

import os;
os.chdir('test')
print(os.getcwd())



C:UsersAhnSeongHyunDocumentseclipseworkspacepython_testsourcetest
OS 모듈
* http://docs.python.org 에 보면 OS 관련 명령어들은 운영체제에 따라서 쓸 수 있는 명령어가 한정되어 있음.




  os.chdir(path)
  Change the current working directory to path.
  Availability: Unix, Windows.


  os.fchdir(fd)
  Change the current working directory to the directory represented by the file descriptor fd. The
  descriptor must refer to an opened directory, not an open file.

  Availability: Unix.

  New in version 2.3.
OS 모듈
      경로에 대한 해당 작업이 가능한지 여부


import os
print(os.access("./test", os.F_OK))

True



import os
print(os.access("./test/test", os.F_OK))

False



o   F_OK : 해당 경로의 존재여부
o   R_OK : 해당 경로의 읽기 가능여부
o   W_OK : 쓰기 가능여부
o   X_OK : 실행가능여부
OS 모듈
     지정한 경로에 존재하는 파일과 디렉토리

import os
print(os.listdir("../")) //상위 디렉토리 지정

['.project', '.pydevproject', 'source']



     디렉토리 생성

import os
os.mkdir("./test1")
print(os.listdir("."))

['test', 'test.py', 'test1']
OS 모듈
     인자로 전달된 디렉토리를 모두 생성(이미 생성되어 있거나 권한 없으면 예외 발생)



import os
os.makedirs('./test1/subtest/')

import os
os.makedirs('./test1/subtest/')

pydev debugger: starting
Traceback (most recent call last):
 File "D:downloadeclipsepluginsorg.python.pydev.debug_2.2.4.2011110216pysrcpydevd.py", line 1307, in <module>
  debugger.run(setup['file'], None, None)
 File "D:downloadeclipsepluginsorg.python.pydev.debug_2.2.4.2011110216pysrcpydevd.py", line 1060, in run
  pydev_imports.execfile(file, globals, locals) #execute the script
 File "D:downloadeclipsepluginsorg.python.pydev.debug_2.2.4.2011110216pysrc_pydev_execfile.py", line 37, in execfile
  exec(compile(contents+"n", file, 'exec'), glob, loc) #execute the script
 File "C:UsersAhnSeongHyunDocumentseclipseworkspacepython_testsourcetest.py", line 7, in <module>
  os.makedirs('./test1/subtest/')
 File "C:Python32libos.py", line 152, in makedirs
  mkdir(name, mode)
WindowsError: [Error 183] 파일이 이미 있으므로 만들 수 없습니다: './test1/subtest/'




import os
os.makedirs('./test1/subtest/t1/t2/t3')
//subtest 까지는 생성되어 있으나 t1, t2, t3 는 없기때문에 생성한다.
OS 모듈
   파일 삭제 : 디렉토리 삭제 아님

import os
os.unlink('./test1/merge_data.fgf')
os.remove('./test1/merge_data.fgf')




   디렉토리 삭제 : 빈디렉토리만 가능
import os
os.rmdir('./test1/subtest/t1/t2/t3')



    디렉토리 연속 삭제

import os
os.removedirs('./test1/subtest/')
OS 모듈
    새이름
import os
os.rename('./test/merge_data.fgf','./test/a.fgf')



    새이름 대신 디렉토리 없으면 자동 생성
import os
os.renames('./test/a.fgf','./test/1/b.fgf')



     경로에 대한 정보 가져오기

import os
print(os.stat('./test/1/b.fgf')).

nt.stat_result(st_mode=33206, st_ino=10696049115166290, st_dev=0, st_nlink=1, st_uid=0, st_gid=0, st_size=38970,
st_atime=1322642803, st_mtime=1322642804, st_ctime=1322642803)
OS 모듈

    경로에 해당하는 파일의 접근시간 수정시간 변경

import os

print(os.stat('./test/1/b.fgf'))
os.utime('./test/1/b.fgf',None) #None 시, 현재 시간으로 변경
print(os.stat('./test/1/b.fgf'))



    umask 설정하기 (수행후, 이전 mask 값이 반환됨.)

os.umask(mask)
OS 모듈

    파이프 생성 읽기, 쓰기 전용ㅇ의 파이프의 파일 디스크립터가 반환된다.

import os
print(os.pipe())
(3, 4)



    파일 디스크립터 이용해서 파일 객체 생성

import os
r, w = os.pipe()
rd = os.fdopen(r)
print(rd.__class__)
OS 모듈
    지정된 명령을 수행하여, 파이프를 연다

import os

p = os.popen("dir","r")
print(p.read())

C 드라이브의 볼륨에는 이름이 없습니다.
볼륨 일련 번호: 6E97-6D43

C:UsersAhnSeongHyunDocumentseclipseworkspacepython_testsource 디렉터리

2011-12-02 오후 08:53 <DIR>       .
2011-12-02 오후 08:53 <DIR>       ..
2011-12-02 오후 08:56 <DIR>       test
2011-12-05 오후 07:36       114 test.py
        1개 파일         114 바이트
        3개 디렉터리 22,413,848,576 바이트 남음
OS 모듈
     현재 운영체제 가져오기
import os
print(os.name)

nt
posix
mac



     환경변수
import os
print(os.environ)



environ({'TMP': 'C:UsersAHNSEO~1AppDataLocalTemp', 'PYTHONIOENCODING': 'MS949',
'COMPUTERNAME': 'AHNSEONGHYUN-PC', 'USERDOMAIN':
OS 모듈


    현재 프로세스 id
import os
print(os.getpid())

6528



   환경변수
os.getenv() // 환경변수 가져오기
os.putenv() // 환경변수 설정하기




    에러코드 출력
os.strerror(code)
OS 모듈
   명령 실행



import os
print(os.system("calc")) // 해당 명령 실행

os.startfile(filepath) // path 지정한 프로그램 수행



   System 과 StartFile 의 차이

- System은 해당 명령을 실행하기 전에 파이썬 프로그램을 멈추고 나서 실행끝나길 기다림.
- startfile 은 해당명령을 실행하고, 파이썬은 따로 실행.
SYS 모듈
    파이썬 스크립트로 넘어온 인자들을 출력해줌.

import sys

print("argv size :", len(sys.argv))

for i, arg in enumerate(sys.argv):
   print(i, arg)

argv size : 1
0 C:UsersAhnSeongHyunDocumentseclipseworkspacepython_testsourcetest.py



    현재 발생한 예외 정보 튜플로 반환

import sys

print(sys.exc_info())
(None, None, None)//예외가 없는 경우
SYS 모듈

try:
   1/0
except:
   exc_class, val, tb_ob = sys.exc_info()
   print(exc_class)
   print(val)
   print(tb_ob)
   print(dir(tb_ob))
   print(tb_ob.tb_lineno)



<class 'ZeroDivisionError'>
division by zero
<traceback object at 0x00FFAAF8>
['tb_frame', 'tb_lasti', 'tb_lineno', 'tb_next']
2
SYS 모듈
   파이썬 설치 경로 및 실행파일
import sys

print(sys.prefix)
print(sys.exec_prefix)
print(sys.executable)

C:Python32
C:Python32
C:Python32python.exe



sys.exit(0) 0 프로세스 정상종료, 0이 아니면 비 정상종료
SYS 모듈

   객체 참조카운트 조회
import sys

t = "test"

print(sys.getrefcount(t))
t1 = t
print(sys.getrefcount(t))

11
12
SYS 모듈
    현재 윈도우 버전 튜플 반환

sys.getwindowsversion()
sys.getwindowsversion(major=6, minor=1, build=7601, platform=2, service_pack='Service Pack 1')




    모듈 정보

import sys
print(sys.modules)
{'heapq': <module 'heapq' from 'C:Python32libheapq.py'>, 'email.iterators': <module 'email.iterators' from
'C:Python32libemailiterators.py'>, 'unicodedata': <module 'unicodedata' from
'C:Python32DLLsunicodedata.pyd'>, 'functools': <module 'functools' from 'C:Python32libfunctools.py'>
SYS 모듈

      기본 인코딩

import sys
print(sys.getdefaultencoding())
utf-8




      표준 입출력, 표준 에러 스트림 파일 객체

import sys

sys.stdout.write("hi")
sys.stderr.write("hi")

hihi
스레드 객체

•   파이썬에서 객체를 사용하려면 threading.Thread를 상속받은 클래스 객체 생성

•   생성자 재정의시 반드시 Thread.__init()__ 수행 해야함.




•   스레드 관련 함수

•   Thread.Start()//스레드 시작

•   Thread.Run()//스레드 주요동작 정의

•   Thread.Join([TimeOut])//스레드 종료 대기, time 만큼만 기다임.
스레드 객체

   Lock 객체



스레드 간의 프로세스 공간의 메모리 공유
하나의 변수에 2개 이상의 스레드 변경을 가할시경쟁상태 돌입
스레드 간의 동기화를 위ㅐ서 Lock 이라는 동기화 객체 지원해줌.



   2가지 상태, 2가지 함수

lock : acquire() : 락 시킴.
unlock : release() : 언락시킴.
from threading import Thread, Lock
import time

count = 10 # 10개의 버그가 있다고 치자.
lock = Lock() # Lock() 객체 선언

class developer( Thread ): #Trhead 상속 받는 Developer 클래스


 def __init__(self, name): # 생성자 재정의
  Thread.__init__(self) # 스레드 초기화 해줌.
  self.name = name
  self.fixed = 0


 def run(self):
  global count
  while 1:
   lock.acquire()
   if count>0:
     count -= 1

    lock.release()
    self.fixed +=1
    time.sleep(0.1)
   else:
    lock.release()
    break

dev_list = []
for name in ['Shin', 'Woo','Choi']:
 dev = developer(name)
 dev_list.append( dev )
 dev.start() #run이 실행됨.

for dev in dev_list:
 dev.join() #타 스레드 종료 대기
 print(dev.name, 'fixed', dev.fixed)


lock 이 없다면, count ==1 인 순간에 여러 스레드가 동시에 진입해서
count 를 수정할 가능성이 있다.
QUEUE 모듈

   파이썬 큐 모듈

     -   queue : 스레드 환경을 고려해서 작성, 동시성 접근 처리 가능
     -   우선순위 큐
     -   스택(lifoqueue)

   queue 모듈 아래 관련 클래스

     –   queue.Queue(maxsize) : 선입선출
     –   queue.LifoQueue : 후입선출
     –   queue.PrioirityQueue : 우선순위 큐(순위, 아이템 : 튜플식 입력)

    * maxsize : 0 이하나 같거나 안쓰면 무제한.
QUEUE 모듈
     기본 예제

import queue



q = queue.Queue() #일반 큐 생성
q.put("apple")
q.put("banana")
q.put(10) #넣기

print(q.qsize()) #큐 사이즈
print(q.get()) # 빼기
print(q.get())

print(q.qsize())

3
apple
banana
1



# 위의 3가지 함수는 3클래스 모두에 있음.
QUEUE 모듈
     큐, 우선순위 큐, 스택 : 내부 정렬 방식이 다르다. 때문에 출력 순서가 다르다.


import queue

def GetItemList(q):
  ret =[]
  n = q.qsize()
  while n >0:
    ret.append(q.get()) #하나씩 가져와서 붙여서 리턴.
    n -=1
  return ret



#일반 큐의 경우

l = "apple,banana,orange"
q = queue.Queue()
for x in l.split(","):
   q.put(x)

print(GetItemList(q))

['apple', 'banana', 'orange']

# 넣은대로 나온다.
QUEUE 모듈
# 후입선출 구조

l = "apple,banana,orange"
q = queue.LifoQueue()
for x in l.split(","):
   q.put(x)

print(GetItemList(q))
['orange', 'banana', 'apple']

# 우선순위대로 출력, 낮은 숫자가 더 우선순위가 높음.

l = "apple,banana,orange"
q = queue.PriorityQueue()
q.put((5,"Apple"))
q.put((15,"gpple"))
q.put((25,"dpple"))

print(GetItemList(q))
[(5, 'Apple'), (15, 'gpple'), (25, 'dpple')]
QUEUE 모듈
큐 생성시, maxsize 지정 가능.

없는데 get 하거나, 풀로 찼는데 put 하면, 큐객체는 블록킹이 된다.



q = queue.Queue(2)
q.put("apple")
q.put("334")
q.put("a243") #여기서 무한대기 됨. 블록킹 상태


무한대기 상태를 피하고자 하는

put_nowait()
get_nowait()

블록킹 상태라면 queue.Full, queue.Empty 예외 발생

q = queue.Queue(2)
q.put("apple")
q.put("334")
q.put_nowait("a243")


일반 적인 get(), put() 에서도 블록킹 지정 및 블록킹 될 시간을 지정할 수 있다.
weakref 모듈
•   참조 카운트가 0 이 되면, 가비지 콜렉션이 발동 없어진다.

•   weakref 모듈은 약한 참조를 만드는데 사용된다.

•   약한 참조는 객체를 얻어올때, 참조카운트의 증가없이 객체를 얻어올수 있는 방법이다.

•   약한 참조 객체는 원본 객체와 동일한 메모리 공간을 가리킨다.

•   원본 객체가 없는 경우, None를 반환한다.
#ref 로 생성

import weakref
import sys

class Apple:
   pass

a = Apple()
print(sys.getrefcount(a))

a.color = "red"
b = a #참조 카운트 증가
print(sys.getrefcount(a))

r = weakref.ref(a) #객체에 대한 약한참조 반환
print(sys.getrefcount(a))

ref_a = r() #이해안되는 부분, 왜 또 생성하나.
print(sys.getrefcount(ref_a))

print(ref_a.color)

a.color = "blue"
print(ref_a.color)

print(a is ref_a)

del a, ref_a
print(r())

pydev debugger: starting
2
3
3
4
red
blue
True
<__main__.Apple object at 0x0219DFB0>
#프록시 이용
import weakref
import sys

class Apple:
   pass

a = Apple()
print(sys.getrefcount(a))

a.color = "red"

b = a #참조 카운트 증가
print(sys.getrefcount(a))
proxy_a = weakref.proxy(a) #객체에 대한 프록시 생성
print(sys.getrefcount(a))

print(proxy_a.color)

a.color = "blue"
print(proxy_a.color)

print(a is proxy_a)

print(a)
print(proxy_a)

pydev debugger: starting
2
3
3
red
blue
False
<__main__.Apple object at 0x021DDFB0>
<__main__.Apple object at 0x021DDFB0>
스레드 객체
•   본 객체에 대한 약한 참조의 생성수, 참조 리스트 반환 예제

import weakref
import sys

class Apple:
   pass

a = Apple()

r = weakref.ref(a)
proxy_a = weakref.proxy(a)

print(weakref.getweakrefcount(a))
print(weakref.getweakrefs(a))

2
[<weakref at 02149ED0; to 'Apple' at 0214DF50>, <weakproxy at 02149F00 to Apple at 0214DF50>]



* 모든 객체가 약한 객체를 생성할수 있는 것은 아니다. 337p 뱀잡기
* 리스트 또는 사전 같은 내장 타입에 대한 약한 참조객체 생성을 하려면 서브클래싱을 통해서 구현 가능하다.
337p

파이썬 스터디 15장

  • 1.
    파이썬 스터디 15장 C/C++ 연동 Ahn Seong Hyun
  • 2.
    OS 모듈  현재 디렉토리 출력 import os; print(os.getcwd()) C:UsersAhnSeongHyunDocumentseclipseworkspacepython_testsource  디렉토리 변경 import os; os.chdir('test') print(os.getcwd()) C:UsersAhnSeongHyunDocumentseclipseworkspacepython_testsourcetest
  • 3.
    OS 모듈 * http://docs.python.org에 보면 OS 관련 명령어들은 운영체제에 따라서 쓸 수 있는 명령어가 한정되어 있음. os.chdir(path) Change the current working directory to path. Availability: Unix, Windows. os.fchdir(fd) Change the current working directory to the directory represented by the file descriptor fd. The descriptor must refer to an opened directory, not an open file. Availability: Unix. New in version 2.3.
  • 4.
    OS 모듈  경로에 대한 해당 작업이 가능한지 여부 import os print(os.access("./test", os.F_OK)) True import os print(os.access("./test/test", os.F_OK)) False o F_OK : 해당 경로의 존재여부 o R_OK : 해당 경로의 읽기 가능여부 o W_OK : 쓰기 가능여부 o X_OK : 실행가능여부
  • 5.
    OS 모듈  지정한 경로에 존재하는 파일과 디렉토리 import os print(os.listdir("../")) //상위 디렉토리 지정 ['.project', '.pydevproject', 'source']  디렉토리 생성 import os os.mkdir("./test1") print(os.listdir(".")) ['test', 'test.py', 'test1']
  • 6.
    OS 모듈  인자로 전달된 디렉토리를 모두 생성(이미 생성되어 있거나 권한 없으면 예외 발생) import os os.makedirs('./test1/subtest/') import os os.makedirs('./test1/subtest/') pydev debugger: starting Traceback (most recent call last): File "D:downloadeclipsepluginsorg.python.pydev.debug_2.2.4.2011110216pysrcpydevd.py", line 1307, in <module> debugger.run(setup['file'], None, None) File "D:downloadeclipsepluginsorg.python.pydev.debug_2.2.4.2011110216pysrcpydevd.py", line 1060, in run pydev_imports.execfile(file, globals, locals) #execute the script File "D:downloadeclipsepluginsorg.python.pydev.debug_2.2.4.2011110216pysrc_pydev_execfile.py", line 37, in execfile exec(compile(contents+"n", file, 'exec'), glob, loc) #execute the script File "C:UsersAhnSeongHyunDocumentseclipseworkspacepython_testsourcetest.py", line 7, in <module> os.makedirs('./test1/subtest/') File "C:Python32libos.py", line 152, in makedirs mkdir(name, mode) WindowsError: [Error 183] 파일이 이미 있으므로 만들 수 없습니다: './test1/subtest/' import os os.makedirs('./test1/subtest/t1/t2/t3') //subtest 까지는 생성되어 있으나 t1, t2, t3 는 없기때문에 생성한다.
  • 7.
    OS 모듈  파일 삭제 : 디렉토리 삭제 아님 import os os.unlink('./test1/merge_data.fgf') os.remove('./test1/merge_data.fgf')  디렉토리 삭제 : 빈디렉토리만 가능 import os os.rmdir('./test1/subtest/t1/t2/t3')  디렉토리 연속 삭제 import os os.removedirs('./test1/subtest/')
  • 8.
    OS 모듈  새이름 import os os.rename('./test/merge_data.fgf','./test/a.fgf')  새이름 대신 디렉토리 없으면 자동 생성 import os os.renames('./test/a.fgf','./test/1/b.fgf')  경로에 대한 정보 가져오기 import os print(os.stat('./test/1/b.fgf')). nt.stat_result(st_mode=33206, st_ino=10696049115166290, st_dev=0, st_nlink=1, st_uid=0, st_gid=0, st_size=38970, st_atime=1322642803, st_mtime=1322642804, st_ctime=1322642803)
  • 9.
    OS 모듈  경로에 해당하는 파일의 접근시간 수정시간 변경 import os print(os.stat('./test/1/b.fgf')) os.utime('./test/1/b.fgf',None) #None 시, 현재 시간으로 변경 print(os.stat('./test/1/b.fgf'))  umask 설정하기 (수행후, 이전 mask 값이 반환됨.) os.umask(mask)
  • 10.
    OS 모듈  파이프 생성 읽기, 쓰기 전용ㅇ의 파이프의 파일 디스크립터가 반환된다. import os print(os.pipe()) (3, 4)  파일 디스크립터 이용해서 파일 객체 생성 import os r, w = os.pipe() rd = os.fdopen(r) print(rd.__class__)
  • 11.
    OS 모듈  지정된 명령을 수행하여, 파이프를 연다 import os p = os.popen("dir","r") print(p.read()) C 드라이브의 볼륨에는 이름이 없습니다. 볼륨 일련 번호: 6E97-6D43 C:UsersAhnSeongHyunDocumentseclipseworkspacepython_testsource 디렉터리 2011-12-02 오후 08:53 <DIR> . 2011-12-02 오후 08:53 <DIR> .. 2011-12-02 오후 08:56 <DIR> test 2011-12-05 오후 07:36 114 test.py 1개 파일 114 바이트 3개 디렉터리 22,413,848,576 바이트 남음
  • 12.
    OS 모듈  현재 운영체제 가져오기 import os print(os.name) nt posix mac  환경변수 import os print(os.environ) environ({'TMP': 'C:UsersAHNSEO~1AppDataLocalTemp', 'PYTHONIOENCODING': 'MS949', 'COMPUTERNAME': 'AHNSEONGHYUN-PC', 'USERDOMAIN':
  • 13.
    OS 모듈  현재 프로세스 id import os print(os.getpid()) 6528  환경변수 os.getenv() // 환경변수 가져오기 os.putenv() // 환경변수 설정하기  에러코드 출력 os.strerror(code)
  • 14.
    OS 모듈  명령 실행 import os print(os.system("calc")) // 해당 명령 실행 os.startfile(filepath) // path 지정한 프로그램 수행  System 과 StartFile 의 차이 - System은 해당 명령을 실행하기 전에 파이썬 프로그램을 멈추고 나서 실행끝나길 기다림. - startfile 은 해당명령을 실행하고, 파이썬은 따로 실행.
  • 15.
    SYS 모듈  파이썬 스크립트로 넘어온 인자들을 출력해줌. import sys print("argv size :", len(sys.argv)) for i, arg in enumerate(sys.argv): print(i, arg) argv size : 1 0 C:UsersAhnSeongHyunDocumentseclipseworkspacepython_testsourcetest.py  현재 발생한 예외 정보 튜플로 반환 import sys print(sys.exc_info()) (None, None, None)//예외가 없는 경우
  • 16.
    SYS 모듈 try: 1/0 except: exc_class, val, tb_ob = sys.exc_info() print(exc_class) print(val) print(tb_ob) print(dir(tb_ob)) print(tb_ob.tb_lineno) <class 'ZeroDivisionError'> division by zero <traceback object at 0x00FFAAF8> ['tb_frame', 'tb_lasti', 'tb_lineno', 'tb_next'] 2
  • 17.
    SYS 모듈  파이썬 설치 경로 및 실행파일 import sys print(sys.prefix) print(sys.exec_prefix) print(sys.executable) C:Python32 C:Python32 C:Python32python.exe sys.exit(0) 0 프로세스 정상종료, 0이 아니면 비 정상종료
  • 18.
    SYS 모듈  객체 참조카운트 조회 import sys t = "test" print(sys.getrefcount(t)) t1 = t print(sys.getrefcount(t)) 11 12
  • 19.
    SYS 모듈  현재 윈도우 버전 튜플 반환 sys.getwindowsversion() sys.getwindowsversion(major=6, minor=1, build=7601, platform=2, service_pack='Service Pack 1')  모듈 정보 import sys print(sys.modules) {'heapq': <module 'heapq' from 'C:Python32libheapq.py'>, 'email.iterators': <module 'email.iterators' from 'C:Python32libemailiterators.py'>, 'unicodedata': <module 'unicodedata' from 'C:Python32DLLsunicodedata.pyd'>, 'functools': <module 'functools' from 'C:Python32libfunctools.py'>
  • 20.
    SYS 모듈  기본 인코딩 import sys print(sys.getdefaultencoding()) utf-8  표준 입출력, 표준 에러 스트림 파일 객체 import sys sys.stdout.write("hi") sys.stderr.write("hi") hihi
  • 21.
    스레드 객체 • 파이썬에서 객체를 사용하려면 threading.Thread를 상속받은 클래스 객체 생성 • 생성자 재정의시 반드시 Thread.__init()__ 수행 해야함. • 스레드 관련 함수 • Thread.Start()//스레드 시작 • Thread.Run()//스레드 주요동작 정의 • Thread.Join([TimeOut])//스레드 종료 대기, time 만큼만 기다임.
  • 22.
    스레드 객체  Lock 객체 스레드 간의 프로세스 공간의 메모리 공유 하나의 변수에 2개 이상의 스레드 변경을 가할시경쟁상태 돌입 스레드 간의 동기화를 위ㅐ서 Lock 이라는 동기화 객체 지원해줌.  2가지 상태, 2가지 함수 lock : acquire() : 락 시킴. unlock : release() : 언락시킴.
  • 23.
    from threading importThread, Lock import time count = 10 # 10개의 버그가 있다고 치자. lock = Lock() # Lock() 객체 선언 class developer( Thread ): #Trhead 상속 받는 Developer 클래스 def __init__(self, name): # 생성자 재정의 Thread.__init__(self) # 스레드 초기화 해줌. self.name = name self.fixed = 0 def run(self): global count while 1: lock.acquire() if count>0: count -= 1 lock.release() self.fixed +=1 time.sleep(0.1) else: lock.release() break dev_list = [] for name in ['Shin', 'Woo','Choi']: dev = developer(name) dev_list.append( dev ) dev.start() #run이 실행됨. for dev in dev_list: dev.join() #타 스레드 종료 대기 print(dev.name, 'fixed', dev.fixed) lock 이 없다면, count ==1 인 순간에 여러 스레드가 동시에 진입해서 count 를 수정할 가능성이 있다.
  • 24.
    QUEUE 모듈  파이썬 큐 모듈 - queue : 스레드 환경을 고려해서 작성, 동시성 접근 처리 가능 - 우선순위 큐 - 스택(lifoqueue)  queue 모듈 아래 관련 클래스 – queue.Queue(maxsize) : 선입선출 – queue.LifoQueue : 후입선출 – queue.PrioirityQueue : 우선순위 큐(순위, 아이템 : 튜플식 입력) * maxsize : 0 이하나 같거나 안쓰면 무제한.
  • 25.
    QUEUE 모듈  기본 예제 import queue q = queue.Queue() #일반 큐 생성 q.put("apple") q.put("banana") q.put(10) #넣기 print(q.qsize()) #큐 사이즈 print(q.get()) # 빼기 print(q.get()) print(q.qsize()) 3 apple banana 1 # 위의 3가지 함수는 3클래스 모두에 있음.
  • 26.
    QUEUE 모듈  큐, 우선순위 큐, 스택 : 내부 정렬 방식이 다르다. 때문에 출력 순서가 다르다. import queue def GetItemList(q): ret =[] n = q.qsize() while n >0: ret.append(q.get()) #하나씩 가져와서 붙여서 리턴. n -=1 return ret #일반 큐의 경우 l = "apple,banana,orange" q = queue.Queue() for x in l.split(","): q.put(x) print(GetItemList(q)) ['apple', 'banana', 'orange'] # 넣은대로 나온다.
  • 27.
    QUEUE 모듈 # 후입선출구조 l = "apple,banana,orange" q = queue.LifoQueue() for x in l.split(","): q.put(x) print(GetItemList(q)) ['orange', 'banana', 'apple'] # 우선순위대로 출력, 낮은 숫자가 더 우선순위가 높음. l = "apple,banana,orange" q = queue.PriorityQueue() q.put((5,"Apple")) q.put((15,"gpple")) q.put((25,"dpple")) print(GetItemList(q)) [(5, 'Apple'), (15, 'gpple'), (25, 'dpple')]
  • 28.
    QUEUE 모듈 큐 생성시,maxsize 지정 가능. 없는데 get 하거나, 풀로 찼는데 put 하면, 큐객체는 블록킹이 된다. q = queue.Queue(2) q.put("apple") q.put("334") q.put("a243") #여기서 무한대기 됨. 블록킹 상태 무한대기 상태를 피하고자 하는 put_nowait() get_nowait() 블록킹 상태라면 queue.Full, queue.Empty 예외 발생 q = queue.Queue(2) q.put("apple") q.put("334") q.put_nowait("a243") 일반 적인 get(), put() 에서도 블록킹 지정 및 블록킹 될 시간을 지정할 수 있다.
  • 29.
    weakref 모듈 • 참조 카운트가 0 이 되면, 가비지 콜렉션이 발동 없어진다. • weakref 모듈은 약한 참조를 만드는데 사용된다. • 약한 참조는 객체를 얻어올때, 참조카운트의 증가없이 객체를 얻어올수 있는 방법이다. • 약한 참조 객체는 원본 객체와 동일한 메모리 공간을 가리킨다. • 원본 객체가 없는 경우, None를 반환한다.
  • 30.
    #ref 로 생성 importweakref import sys class Apple: pass a = Apple() print(sys.getrefcount(a)) a.color = "red" b = a #참조 카운트 증가 print(sys.getrefcount(a)) r = weakref.ref(a) #객체에 대한 약한참조 반환 print(sys.getrefcount(a)) ref_a = r() #이해안되는 부분, 왜 또 생성하나. print(sys.getrefcount(ref_a)) print(ref_a.color) a.color = "blue" print(ref_a.color) print(a is ref_a) del a, ref_a print(r()) pydev debugger: starting 2 3 3 4 red blue True <__main__.Apple object at 0x0219DFB0>
  • 31.
    #프록시 이용 import weakref importsys class Apple: pass a = Apple() print(sys.getrefcount(a)) a.color = "red" b = a #참조 카운트 증가 print(sys.getrefcount(a)) proxy_a = weakref.proxy(a) #객체에 대한 프록시 생성 print(sys.getrefcount(a)) print(proxy_a.color) a.color = "blue" print(proxy_a.color) print(a is proxy_a) print(a) print(proxy_a) pydev debugger: starting 2 3 3 red blue False <__main__.Apple object at 0x021DDFB0> <__main__.Apple object at 0x021DDFB0>
  • 32.
    스레드 객체 • 본 객체에 대한 약한 참조의 생성수, 참조 리스트 반환 예제 import weakref import sys class Apple: pass a = Apple() r = weakref.ref(a) proxy_a = weakref.proxy(a) print(weakref.getweakrefcount(a)) print(weakref.getweakrefs(a)) 2 [<weakref at 02149ED0; to 'Apple' at 0214DF50>, <weakproxy at 02149F00 to Apple at 0214DF50>] * 모든 객체가 약한 객체를 생성할수 있는 것은 아니다. 337p 뱀잡기 * 리스트 또는 사전 같은 내장 타입에 대한 약한 참조객체 생성을 하려면 서브클래싱을 통해서 구현 가능하다. 337p