Ví dụ về bộ nhớ dùng chung IPC Python

Điều này mô tả mô-đun sysv_ipc cho phép Python truy cập vào các ẩn dụ liên quá trình của Hệ thống V, bộ nhớ dùng chung và hàng đợi tin nhắn trên hầu hết (tất cả?) *các hương vị nix. Ví dụ bao gồm macOS/OS X, Linux, FreeBSD, OpenSolaris 2008. 11, HPUX và AIX. Nó cũng có thể hoạt động trong Windows với thư viện như Cygwin

Nó hoạt động với Python ≥ 3. 6. Nó được phát hành theo giấy phép BSD

Bạn có thể tải xuống sysv_ipc phiên bản 1. 1. 0 ([md5sum], [sha1sum], [sha256sum]) chứa mã nguồn, thiết lập. py, hướng dẫn cài đặt và. bạn có thể đọc về

Bạn cũng có thể muốn đọc về một số

Bạn có thể quan tâm đến mô-đun rất giống posix_ipc cung cấp quyền truy cập Python vào các nguyên mẫu POSIX IPC. POSIX IPC dễ sử dụng hơn một chút so với SysV IPC, nhưng không phải hệ điều hành nào cũng hỗ trợ hoàn toàn

Mô-đun sysv_ipc

Nhảy tới , , hoặc

Chức năng mô-đun

Attach(id, [address = None, [flags = 0]]) Đính kèm bộ nhớ dùng chung (hiện có) có id đã cho và trả về một đối tượng SharedMemory mới. Xem để biết chi tiết về các tham số addressflags

Phương pháp này chỉ hữu ích trong những trường hợp khá bất thường. bạn có thể không cần nó

ftok(đường dẫn, id, [silence_warning = False]) Cuộc gọi ftok(path, id). Lưu ý rằng , và chức năng này sẽ đưa ra cảnh báo cho hiệu ứng đó trừ khi
try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
0 là True. remove_semaphore(id)Xóa semaphore với id đã cho. remove_shared_memory(id)Xóa bộ nhớ dùng chung với id đã cho. remove_message_queue(id)Xóa hàng đợi tin nhắn với id đã cho

hằng số mô-đun

IPC_CREAT, IPC_EXCL và IPC_CREX
try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
4 và
try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
5 là các cờ được sử dụng khi tạo các đối tượng IPC. Chúng là duy nhất theo bit và có thể được ORed cùng nhau.
try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
6 là viết tắt của
try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
7

Khi được chuyển đến hàm tạo của đối tượng IPC,

try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
4 cho biết bạn muốn tạo một đối tượng mới hoặc mở một đối tượng hiện có. Nếu bạn muốn cuộc gọi không thành công nếu một đối tượng có khóa đó đã tồn tại, hãy chỉ định cả cờ
try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
5

IPC_PRIVATE Đây là một giá trị đặc biệt có thể được chuyển thay cho khóa. Nó ngụ ý rằng đối tượng IPC chỉ nên có sẵn cho quá trình tạo hoặc các quá trình con của nó (e. g. những cái được tạo bằng sysv_ipc0). KEY_MIN và KEY_MAX Biểu thị phạm vi khóa mà mô-đun này chấp nhận. Hệ điều hành của bạn có thể giới hạn các phím ở phạm vi nhỏ hơn tùy thuộc vào typedef của sysv_ipc1

Các phím được tạo ngẫu nhiên bởi mô-đun này nằm trong phạm vi sysv_ipc2. Đó là loại an toàn trừ khi hệ điều hành của bạn có một định nghĩa rất kỳ lạ về sysv_ipc1

SEMAPHORE_VALUE_MAX Giá trị tối đa của một semaphore. PAGE_SIZEKích thước trang bộ nhớ của hệ điều hành, tính bằng byte. Có lẽ nên tạo các phân đoạn bộ nhớ dùng chung theo bội số của kích thước này. SEMAPHORE_TIMEOUT_SUPPORTEDTrue nếu nền tảng hỗ trợ semaphore chờ theo thời gian, nếu không thì Sai. SHM_RDONLYChuyển cờ này cho sysv_ipc4 để đính kèm phân đoạn ở chế độ chỉ đọc. SHM_RNDBạn có thể không cần điều này, nhưng nó có thể được sử dụng khi đính kèm bộ nhớ dùng chung để buộc địa chỉ được làm tròn xuống SHMLBA. Xem trang hướng dẫn của hệ thống cho sysv_ipc5 để biết thêm thông tin. SHM_HUGETLB, SHM_NORESERVE và SHM_REMAPCó thể bạn không cần những thứ này. Chúng là các cờ dành riêng cho Linux có thể được chuyển đến hàm tạo SharedMemory hoặc hàm sysv_ipc6 trong trường hợp SHM_REMAP. Xem trang hướng dẫn của hệ thống cho sysv_ipc7 và sysv_ipc5 để biết thêm thông tin

Lỗi mô-đun

Ngoài các lỗi Python tiêu chuẩn (e. g. sysv_ipc9), mô-đun này phát sinh các lỗi tùy chỉnh. Những lỗi này bao gồm các tình huống cụ thể đối với IPC

Lỗi Loại lỗi cơ sở cho tất cả các lỗi tùy chỉnh trong mô-đun này. Lỗi này đôi khi tự xuất hiện nhưng hầu như bạn sẽ luôn thấy một lỗi cụ thể hơn. InternalErrorChỉ ra rằng có điều gì đó rất sai trong mã mô-đun. Vui lòng báo cáo điều này cho người bảo trì. PermissionsErrorCho biết rằng bạn đã thử điều gì đó mà các quyền trên đối tượng IPC không cho phép. ExistentialErrorChỉ ra lỗi liên quan đến sự tồn tại hoặc không tồn tại của đối tượng IPC. BusyErrorRaised khi một semaphore gọi đến posix_ipc0 hoặc posix_ipc1 hết thời gian hoặc sẽ buộc phải đợi khi thuộc tính posix_ipc2 của nó là Sai. NotAttachedErrorRaised khi một quá trình cố gắng đọc hoặc ghi vào một phân đoạn bộ nhớ dùng chung mà nó không được đính kèm

Lớp Semaphore

Đây là một tay cầm cho một semaphore

phương pháp

Semaphore(key, [flags = 0, [mode = 0600, [initial_value = 0]]]) Tạo semaphore mới hoặc mở semaphore hiện có

khóa phải là posix_ipc3, posix_ipc4 hoặc một số nguyên > posix_ipc5 và ≤ posix_ipc6. Nếu khóa là posix_ipc3, mô-đun sẽ chọn một khóa ngẫu nhiên chưa sử dụng

Các cờ xác định xem bạn muốn tạo một semaphore mới hay mở một semaphore hiện có

  • Với các cờ được đặt thành mặc định là posix_ipc8, mô-đun cố gắng mở một semaphore hiện có được xác định bằng khóa và tăng posix_ipc9 nếu semaphore đó không tồn tại
  • Với các cờ được đặt thành
    try:
        sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
    except sysv_ipc.ExistentialError:
        # One of my peers created the semaphore already
        sem = sysv_ipc.Semaphore(42)
        # Waiting for that peer to do the first acquire or release
        while not sem.o_time:
            time.sleep(.1)
    else:
        # Initializing sem.o_time to nonzero value
        sem.release()
    # Now the semaphore is safe to use.
    
    4, mô-đun sẽ mở semaphore được xác định bằng khóa hoặc tạo một semaphore mới nếu không tồn tại semaphore như vậy. Không nên sử dụng riêng
    try:
        sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
    except sysv_ipc.ExistentialError:
        # One of my peers created the semaphore already
        sem = sysv_ipc.Semaphore(42)
        # Waiting for that peer to do the first acquire or release
        while not sem.o_time:
            time.sleep(.1)
    else:
        # Initializing sem.o_time to nonzero value
        sem.release()
    # Now the semaphore is safe to use.
    
    4. (Nhìn thấy. )
  • Với các cờ được đặt thành
    try:
        sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
    except sysv_ipc.ExistentialError:
        # One of my peers created the semaphore already
        sem = sysv_ipc.Semaphore(42)
        # Waiting for that peer to do the first acquire or release
        while not sem.o_time:
            time.sleep(.1)
    else:
        # Initializing sem.o_time to nonzero value
        sem.release()
    # Now the semaphore is safe to use.
    
    6 (_______0_______7), mô-đun sẽ tạo một semaphore mới được xác định bằng khóa. Nếu một semaphore với khóa đó đã tồn tại, cuộc gọi sẽ tăng một số posix_ipc9. Giá trị_ban_đầu bị bỏ qua trừ khi cả hai cờ này được chỉ định hoặc nếu semaphore ở chế độ chỉ đọc

Khi mở một semaphore hiện có, chế độ sẽ bị bỏ qua

thu được([thời gian chờ = Không có, [delta = 1]])Đợi (có điều kiện) cho đến khi giá trị của semaphore > 0 và sau đó trả về, làm giảm semaphore

Thời gian chờ (có thể là thời gian trôi nổi) chỉ định cuộc gọi này sẽ đợi bao nhiêu giây, nếu có

Ngữ nghĩa của thời gian chờ

  • Thời gian chờ là Không có (mặc định) có nghĩa là không có giới hạn thời gian. Cuộc gọi sẽ không trở lại cho đến khi điều kiện chờ của nó được thỏa mãn
  • Khi thời gian chờ là 0, cuộc gọi sẽ tăng sysv_ipc5 nếu nó không thể nhận được semaphore ngay lập tức. Vì nó sẽ quay lại ngay lập tức nếu không được yêu cầu đợi, đây có thể được coi là chế độ "không chặn"
  • Khi thời gian chờ > 0, cuộc gọi sẽ đợi không quá thời gian chờ vài giây trước khi quay lại (đã nhận được semaphore) hoặc tăng sysv_ipc5

Khi cuộc gọi trở lại, giá trị của semaphore giảm theo delta (hay chính xác hơn là sysv_ipc7) mặc định là 1

Trên các nền tảng không hỗ trợ lệnh gọi API sysv_ipc8, tất cả thời gian chờ (bao gồm cả số 0) được coi là vô hạn. Cuộc gọi sẽ không trở lại cho đến khi điều kiện chờ của nó được thỏa mãn

Hầu hết các nền tảng cung cấp sysv_ipc8. macOS là một ngoại lệ đáng chú ý. Hằng số Boolean của mô-đun id0 là True trên các nền tảng hỗ trợ sysv_ipc8

phát hành([delta = 1])Phát hành (tăng) semaphore

Giá trị của semaphore tăng theo delta (hay chính xác hơn là sysv_ipc7) mặc định là 1

P() Một từ đồng nghĩa với id3 có cùng tham số

"P" là viết tắt của prolaag hoặc probeer te verlagen (cố giảm), tên ban đầu do Edsger Dijkstra đặt

V() Một từ đồng nghĩa với id4 có cùng tham số

"V" là viết tắt của verhoog (tăng), tên ban đầu được đặt bởi Edsger Dijkstra

Z([timeout = None]) Chặn cho đến khi zee zemaphore bằng 0

Thời gian chờ có cùng ý nghĩa như được mô tả trong id3

remove() Loại bỏ (xóa) semaphore khỏi hệ thống

Theo như tôi có thể nói, hiệu quả của việc xóa một semaphore mà các quy trình khác vẫn đang sử dụng phụ thuộc vào hệ điều hành. Kiểm tra các trang hướng dẫn của hệ thống để biết id6

Thuộc tính

khóa (chỉ đọc)Khóa được chuyển trong lệnh gọi hàm tạo. id (chỉ đọc) id được hệ điều hành gán cho semaphore này. valueGiá trị nguyên của semaphore. undoDefaults thành Sai

Khi True, các hoạt động thay đổi giá trị của semaphore sẽ được hoàn tác (đảo ngược) khi quá trình thoát. Lưu ý rằng khi một quy trình thoát, thao tác hoàn tác có thể ngụ ý rằng giá trị của semaphore sẽ trở nên âm hoặc vượt quá giá trị tối đa của nó. Hành vi trong trường hợp này phụ thuộc vào hệ thống, điều đó có nghĩa là việc sử dụng cờ này có thể khiến mã của bạn không thể di chuyển được

blockDefaults thành True, có nghĩa là các cuộc gọi đến id7 và id8 sẽ không trả lại cho đến khi các điều kiện chờ của chúng được thỏa mãn

Khi Sai, các cuộc gọi này sẽ không chặn mà thay vào đó sẽ gây ra lỗi nếu chúng không thể quay lại ngay lập tức

modeCác bit quyền của semaphore

Mẹo. mã Python sau đây sẽ hiển thị chế độ theo bát phân
id9

uidId người dùng của semaphore. gidId nhóm của semaphore. cuid (chỉ đọc)Id người dùng của người tạo semaphore. cgid (chỉ đọc)Id nhóm của người tạo semaphore. last_pid (chỉ đọc) PID của quy trình được gọi lần cuối là address0 (posix_ipc0, address2 hoặc posix_ipc1) trên semaphore này

Linux và macOS cũng thiết lập điều này khi giá trị của semaphore bị thay đổi, mặc dù làm như vậy không phù hợp với thông số kỹ thuật POSIX. Xem lỗi nhân Linux 112271

wait_for_nonzero (chỉ đọc)Số tiến trình đang đợi giá trị của semaphore trở thành khác không (i. e. số đang chờ trong cuộc gọi đến posix_ipc0). wait_for_zero (chỉ đọc)Số tiến trình đang đợi giá trị của semaphore trở thành 0 (i. e. số đang chờ trong cuộc gọi tới posix_ipc1). o_time (chỉ đọc)Lần cuối cùng address0 (i. e. posix_ipc0, address2 hoặc posix_ipc1) đã được gọi trên semaphore này

Hỗ trợ trình quản lý bối cảnh

Các semaphores này cung cấp các phương thức flags0 và flags1 để chúng có thể được sử dụng trong trình quản lý bối cảnh. Ví dụ --

with sysv_ipc.Semaphore(name) as sem:
    # Do something...

Bước vào ngữ cảnh sẽ nhận được semaphore, thoát khỏi ngữ cảnh sẽ giải phóng semaphore. Xem flags2 để biết ví dụ hoàn chỉnh

Đây là một điều khiển cho một phân đoạn bộ nhớ dùng chung

Hỗ trợ giao thức đệm

Ngoài các phương thức và thuộc tính được mô tả bên dưới, flags3 hỗ trợ giao thức bộ đệm của Python, có nghĩa là bạn có thể tạo các đối tượng flags4 và flags5 dựa trên phân đoạn flags3. Xem flags7 để biết ví dụ

phương pháp

SharedMemory(key, [flags = 0, [mode = 0600, [size = 0 or PAGE_SIZE, [init_character = ' ']]]]] Tạo phân đoạn bộ nhớ dùng chung mới hoặc mở phân đoạn bộ nhớ hiện có. Bộ nhớ được tự động đính kèm

khóa phải là posix_ipc3, posix_ipc4 hoặc một số nguyên > posix_ipc8 và ≤ posix_ipc6. Nếu khóa là posix_ipc3, mô-đun sẽ chọn một khóa ngẫu nhiên chưa sử dụng

Các cờ chỉ định xem bạn muốn tạo một phân đoạn bộ nhớ dùng chung mới hay mở một phân đoạn hiện có

  • Với các cờ được đặt thành mặc định là posix_ipc8, mô-đun sẽ cố gắng mở một phân đoạn bộ nhớ dùng chung hiện có được xác định bằng khóa và tăng posix_ipc9 nếu nó không tồn tại
  • Với các cờ được đặt thành
    try:
        sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
    except sysv_ipc.ExistentialError:
        # One of my peers created the semaphore already
        sem = sysv_ipc.Semaphore(42)
        # Waiting for that peer to do the first acquire or release
        while not sem.o_time:
            time.sleep(.1)
    else:
        # Initializing sem.o_time to nonzero value
        sem.release()
    # Now the semaphore is safe to use.
    
    4, mô-đun sẽ mở phân đoạn bộ nhớ dùng chung được xác định bằng khóa hoặc tạo một phân đoạn mới nếu không có phân đoạn đó tồn tại. Không nên sử dụng riêng
    try:
        sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
    except sysv_ipc.ExistentialError:
        # One of my peers created the semaphore already
        sem = sysv_ipc.Semaphore(42)
        # Waiting for that peer to do the first acquire or release
        while not sem.o_time:
            time.sleep(.1)
    else:
        # Initializing sem.o_time to nonzero value
        sem.release()
    # Now the semaphore is safe to use.
    
    4. (Nhìn thấy. )
  • Với các cờ được đặt thành
    try:
        sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
    except sysv_ipc.ExistentialError:
        # One of my peers created the semaphore already
        sem = sysv_ipc.Semaphore(42)
        # Waiting for that peer to do the first acquire or release
        while not sem.o_time:
            time.sleep(.1)
    else:
        # Initializing sem.o_time to nonzero value
        sem.release()
    # Now the semaphore is safe to use.
    
    6 (_______0_______7), mô-đun sẽ tạo một phân đoạn bộ nhớ dùng chung mới được xác định bằng khóa. Nếu một phân khúc với khóa đó đã tồn tại, cuộc gọi sẽ tăng một posix_ipc9

    Khi cả

    try:
        sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
    except sysv_ipc.ExistentialError:
        # One of my peers created the semaphore already
        sem = sysv_ipc.Semaphore(42)
        # Waiting for that peer to do the first acquire or release
        while not sem.o_time:
            time.sleep(.1)
    else:
        # Initializing sem.o_time to nonzero value
        sem.release()
    # Now the semaphore is safe to use.
    
    6 được chỉ định và người gọi có quyền ghi, mỗi byte trong phân đoạn bộ nhớ mới sẽ được khởi tạo thành giá trị của init_character

Giá trị của kích thước phụ thuộc vào việc một người đang mở một phân khúc hiện có hay tạo một phân khúc mới

  • Khi mở một phân khúc hiện có, kích thước phải ≤ kích thước của phân khúc hiện có. Số 0 luôn hợp lệ
  • Khi tạo một phân đoạn mới, nhiều hệ điều hành (hầu hết? tất cả?) nhấn mạnh vào kích thước > posix_ipc8. Ngoài ra, một số làm tròn kích thước lên bội số tiếp theo của PAGE_SIZE

Mô-đun này cung cấp kích thước mặc định là ftok()2 khi chỉ định

try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
6 và ngược lại là posix_ipc8

attachment([address = None, [flags = 0]])Đính kèm tiến trình này vào bộ nhớ dùng chung. Phải gắn thẻ nhớ trước khi gọi ftok()5 hoặc ftok()6. Lưu ý rằng hàm tạo tự động gắn bộ nhớ, do đó bạn sẽ không cần gọi phương thức này trừ khi bạn tách nó ra một cách rõ ràng và sau đó muốn sử dụng lại

Tham số địa chỉ cho phép một người chỉ định (dưới dạng Python dài) một địa chỉ bộ nhớ để đính kèm phân đoạn. Vượt qua Không có (mặc định) tương đương với việc chuyển NULL sang sysv_ipc5. Xem trang man của chức năng đó để biết chi tiết

Các cờ chủ yếu chỉ có liên quan nếu một người chỉ định một địa chỉ cụ thể. Một ngoại lệ là cờ ftok()8, đáng ngạc nhiên là, đính kèm phân đoạn chỉ đọc

Lưu ý rằng trên một số (và có lẽ là tất cả) nền tảng, mỗi cuộc gọi đến ____80_______6 sẽ tăng số lượng "được đính kèm" của hệ thống. Do đó, nếu mỗi cuộc gọi tới ____80_______6 không được ghép nối với một cuộc gọi tới ____0_______01, thì số lượng "được đính kèm" của hệ thống cho phân đoạn bộ nhớ dùng chung sẽ không về 0 khi quá trình thoát. Do đó, phân đoạn bộ nhớ dùng chung có thể không biến mất ngay cả khi người tạo của nó gọi

try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
02 và thoát

detach() Tách tiến trình này khỏi bộ nhớ dùng chung. read([byte_count = 0, [offset = 0]]) Đọc tối đa byte_count byte từ phân đoạn bộ nhớ dùng chung bắt đầu từ offset và trả về chúng dưới dạng một đối tượng byte (giống như một
try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
03 trong Python 2)

Nếu byte_count bằng 0 (mặc định) thì toàn bộ bộ đệm được trả về

Phương pháp này sẽ không bao giờ cố gắng đọc qua phần cuối của phân đoạn bộ nhớ dùng chung, ngay cả khi offset + byte_count vượt quá kích thước của phân đoạn bộ nhớ. Trong trường hợp đó, các byte từ phần bù đến phần cuối của phân đoạn được trả về

write(some_bytes, [offset = 0])Ghi byte (i. e.
try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
03 trong Python 2) vào bộ nhớ dùng chung, bắt đầu từ phần bù. Chuyển một đối tượng Unicode có thể hoạt động, nhưng làm như vậy không được hỗ trợ và có thể bị phản đối rõ ràng trong phiên bản tương lai

Nếu phần bù + dữ liệu sẽ ghi bên ngoài phân khúc, chức năng này sẽ tăng sysv_ipc9

Các byte có thể chứa các byte NULL được nhúng (

try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
06)

remove() Xóa (hủy) bộ nhớ dùng chung. Lưu ý rằng sự phá hủy thực tế của phân đoạn chỉ xảy ra khi tất cả các quy trình đã tách ra

Thuộc tính

khóa (chỉ đọc) Khóa được cung cấp trong hàm tạo. id (chỉ đọc) id được hệ điều hành gán cho phân đoạn này. kích thước (chỉ đọc) Kích thước của phân đoạn tính bằng byte. địa chỉ (chỉ đọc) Địa chỉ của phân khúc dưới dạng Python dài. được đính kèm (chỉ đọc)Nếu Đúng, phân đoạn này hiện được đính kèm. last_attach_time (chỉ đọc)Lần cuối cùng một quy trình đính kèm phân đoạn này. last_detach_time (chỉ đọc)Lần cuối cùng một quy trình tách phân đoạn này. last_change_time (chỉ đọc)Lần cuối cùng một quy trình thay đổi uid, gid hoặc chế độ trên phân đoạn này. Creator_pid (chỉ đọc)PID của quy trình đã tạo phân đoạn này. last_pid (chỉ đọc) PID của quy trình cuối cùng nhất để gắn hoặc tách phân đoạn này. number_attached (chỉ đọc)Số lượng quy trình được đính kèm với phân đoạn này. uidId người dùng của phân khúc. gidId nhóm của phân khúc. chế độ Các bit cho phép của bộ nhớ dùng chung

Mẹo. mã Python sau đây sẽ hiển thị chế độ theo bát phân

try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
07

cuid (chỉ đọc)Id người dùng của người tạo phân khúc. cgid (chỉ đọc)Id nhóm của người tạo phân khúc

Lớp MessageQueue

Đây là một điều khiển cho hàng đợi tin nhắn FIFO

phương pháp

MessageQueue(key, [flags = 0, [mode = 0600, [max_message_size = 2048]]]) Tạo hàng đợi tin nhắn mới hoặc mở hàng đợi tin nhắn hiện có

khóa phải là posix_ipc3, posix_ipc4 hoặc một số nguyên > posix_ipc8 và ≤ posix_ipc6. Nếu khóa là posix_ipc3, mô-đun sẽ chọn một khóa ngẫu nhiên chưa sử dụng

Các cờ chỉ định xem bạn muốn tạo hàng đợi mới hay mở hàng đợi hiện có

  • Với các cờ được đặt thành mặc định là posix_ipc8, mô-đun sẽ cố gắng mở một hàng đợi thư hiện có được xác định bằng khóa và tăng posix_ipc9 nếu nó không tồn tại
  • Với các cờ được đặt thành
    try:
        sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
    except sysv_ipc.ExistentialError:
        # One of my peers created the semaphore already
        sem = sysv_ipc.Semaphore(42)
        # Waiting for that peer to do the first acquire or release
        while not sem.o_time:
            time.sleep(.1)
    else:
        # Initializing sem.o_time to nonzero value
        sem.release()
    # Now the semaphore is safe to use.
    
    4, mô-đun sẽ mở hàng đợi tin nhắn được xác định bằng khóa hoặc tạo một hàng đợi mới nếu không có hàng đợi như vậy tồn tại
  • Với các cờ được đặt thành
    try:
        sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
    except sysv_ipc.ExistentialError:
        # One of my peers created the semaphore already
        sem = sysv_ipc.Semaphore(42)
        # Waiting for that peer to do the first acquire or release
        while not sem.o_time:
            time.sleep(.1)
    else:
        # Initializing sem.o_time to nonzero value
        sem.release()
    # Now the semaphore is safe to use.
    
    6 (_______0_______7), mô-đun sẽ tạo một hàng đợi tin nhắn mới được xác định bằng khóa. Nếu một hàng đợi với khóa đó đã tồn tại, lệnh gọi sẽ tạo ra một posix_ipc9

Max_message_size có thể được tăng lên từ mặc định, nhưng hãy lưu ý các vấn đề được thảo luận trong

gửi(tin nhắn, [block = True, [type = 1]])Đặt tin nhắn vào hàng đợi

Thông báo phải là một đối tượng byte (a. k. a.

try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
03 trong Python 2) và có thể chứa NULL nhúng (ASCII
try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
20). Chuyển một đối tượng Unicode có thể hoạt động, nhưng làm như vậy không được hỗ trợ và có thể bị phản đối rõ ràng trong phiên bản tương lai

Cờ khối chỉ định cuộc gọi có nên đợi hay không nếu tin nhắn không thể gửi được (ví dụ: nếu hàng đợi đầy). Khi khối là _______0_______21, cuộc gọi sẽ tăng _______80_______5 nếu không thể gửi tin nhắn ngay lập tức

Loại được liên kết với tin nhắn và có liên quan khi gọi

try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
23. Nó phải > 0

get([block = True, [type = 0]])Nhận một tin nhắn từ hàng đợi, trả về một bộ giá trị của
try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
24. Thông báo là một đối tượng byte (a. k. a.
try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
03 bằng Python 2)

Cờ khối chỉ định cuộc gọi có nên chờ hay không nếu không có thông báo nào thuộc loại được chỉ định để truy xuất. Khi khối là _______0_______21, cuộc gọi sẽ tăng _______80_______5 nếu không thể nhận được tin nhắn ngay lập tức

Loại cho phép một số kiểm soát đối với thông báo nào được truy xuất

  • Khi gõ
    try:
        sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
    except sysv_ipc.ExistentialError:
        # One of my peers created the semaphore already
        sem = sysv_ipc.Semaphore(42)
        # Waiting for that peer to do the first acquire or release
        while not sem.o_time:
            time.sleep(.1)
    else:
        # Initializing sem.o_time to nonzero value
        sem.release()
    # Now the semaphore is safe to use.
    
    28, cuộc gọi trả về tin nhắn đầu tiên trên hàng đợi bất kể loại của nó
  • Khi gõ
    try:
        sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
    except sysv_ipc.ExistentialError:
        # One of my peers created the semaphore already
        sem = sysv_ipc.Semaphore(42)
        # Waiting for that peer to do the first acquire or release
        while not sem.o_time:
            time.sleep(.1)
    else:
        # Initializing sem.o_time to nonzero value
        sem.release()
    # Now the semaphore is safe to use.
    
    29, cuộc gọi trả về tin nhắn đầu tiên của loại đó
  • Khi gõ
    try:
        sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
    except sysv_ipc.ExistentialError:
        # One of my peers created the semaphore already
        sem = sysv_ipc.Semaphore(42)
        # Waiting for that peer to do the first acquire or release
        while not sem.o_time:
            time.sleep(.1)
    else:
        # Initializing sem.o_time to nonzero value
        sem.release()
    # Now the semaphore is safe to use.
    
    30, cuộc gọi trả về thông báo đầu tiên của loại thấp nhất là ≤ giá trị tuyệt đối của loại
remove() Loại bỏ (xóa) hàng đợi tin nhắn

Thuộc tính

khóa (chỉ đọc) Khóa được cung cấp trong hàm tạo. id (chỉ đọc) id được hệ điều hành gán cho hàng đợi này. max_sizeKích thước tối đa của hàng đợi tính bằng byte. Chỉ một quy trình có "đặc quyền phù hợp" mới có thể tăng giá trị này và trên một số hệ thống, thậm chí điều đó sẽ không hoạt động. Xem để biết chi tiết. last_send_time (chỉ đọc) Lần cuối cùng một tin nhắn được đưa vào hàng đợi. last_receive_time (chỉ đọc) Lần cuối nhận được tin nhắn từ hàng đợi. last_change_time (chỉ đọc)Lần cuối cùng một tiến trình thay đổi thuộc tính của hàng đợi. last_send_pid (chỉ đọc)Id của quá trình gửi tin nhắn gần đây nhất. last_receive_pid (chỉ đọc)Id của quá trình gần đây nhất để nhận tin nhắn. current_messages (chỉ đọc)Số lượng tin nhắn hiện có trong hàng đợi. uidId người dùng của hàng đợi. gidId nhóm của hàng đợi. chế độ Các bit quyền của hàng đợi

Mẹo. mã Python sau đây sẽ hiển thị chế độ theo bát phân

try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
07

cuid (chỉ đọc)Id người dùng của người tạo hàng đợi. cgid (chỉ đọc)Id nhóm của người tạo hàng đợi

Mẹo sử dụng

Mã mẫu

Mô-đun này đi kèm với bốn bộ mã trình diễn trong thư mục

try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
32

  • try:
        sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
    except sysv_ipc.ExistentialError:
        # One of my peers created the semaphore already
        sem = sysv_ipc.Semaphore(42)
        # Waiting for that peer to do the first acquire or release
        while not sem.o_time:
            time.sleep(.1)
    else:
        # Initializing sem.o_time to nonzero value
        sem.release()
    # Now the semaphore is safe to use.
    
    33 minh họa việc sử dụng semaphores và bộ nhớ dùng chung để chia sẻ dữ liệu giữa các tiến trình
  • try:
        sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
    except sysv_ipc.ExistentialError:
        # One of my peers created the semaphore already
        sem = sysv_ipc.Semaphore(42)
        # Waiting for that peer to do the first acquire or release
        while not sem.o_time:
            time.sleep(.1)
    else:
        # Initializing sem.o_time to nonzero value
        sem.release()
    # Now the semaphore is safe to use.
    
    34 minh họa việc sử dụng hàng đợi tin nhắn để chia sẻ dữ liệu giữa các quy trình
  • try:
        sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
    except sysv_ipc.ExistentialError:
        # One of my peers created the semaphore already
        sem = sysv_ipc.Semaphore(42)
        # Waiting for that peer to do the first acquire or release
        while not sem.o_time:
            time.sleep(.1)
    else:
        # Initializing sem.o_time to nonzero value
        sem.release()
    # Now the semaphore is safe to use.
    
    35 thể hiện việc tạo các đối tượng flags4 và flags5 trên bộ nhớ dùng chung
  • try:
        sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
    except sysv_ipc.ExistentialError:
        # One of my peers created the semaphore already
        sem = sysv_ipc.Semaphore(42)
        # Waiting for that peer to do the first acquire or release
        while not sem.o_time:
            time.sleep(.1)
    else:
        # Initializing sem.o_time to nonzero value
        sem.release()
    # Now the semaphore is safe to use.
    
    38 thể hiện việc sử dụng các cá thể semaphore trong trình quản lý ngữ cảnh (câu lệnh ______0_______39)

Điểm yếu của ftok()

Hầu hết mã mẫu IPC của Hệ thống V đề xuất ftok() để tạo khóa số nguyên ít nhiều ngẫu nhiên. Tuy nhiên, nó không đảm bảo rằng khóa mà nó tạo ra không được sử dụng. Nếu ftok() cung cấp cho ứng dụng của bạn một khóa mà một số ứng dụng khác đang sử dụng, thì ứng dụng của bạn đang gặp sự cố trừ khi nó có cơ chế thứ hai đáng tin cậy để tạo khóa. Và nếu đúng như vậy, tại sao không bỏ ftok() và chỉ sử dụng cơ chế thứ hai?

Đây là điểm yếu của ftok() -- không đảm bảo sẽ cung cấp cho bạn những gì bạn muốn. Trang man BSD cho

try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
45 cho biết "quy trình hoàn toàn có thể trả về các khóa trùng lặp". Thuật ngữ "hoàn toàn có thể" không được định lượng, nhưng giả sử nó có nghĩa là một phần mười của một phần trăm. Ai muốn có tỷ lệ 1 trên 1000 về một thất bại thảm hại trong chương trình của họ, hoặc thậm chí là 1 trên 10000?

Mô-đun này loại bỏ nhu cầu về ftok() bằng cách tạo các khóa ngẫu nhiên cho bạn. Nếu ứng dụng của bạn không thể sử dụng các khóa được tạo tự động của sysv_ipc vì ứng dụng cần biết khóa trước, mã hóa cứng một số ngẫu nhiên như 123456 trong ứng dụng của bạn có thể không tệ hơn việc sử dụng ftok() và có lợi thế là không che giấu các hạn chế của nó

Mô-đun này cung cấp ftok() trong trường hợp bạn muốn thử nghiệm với nó. Tuy nhiên, để nhấn mạnh điểm yếu của nó, phiên bản ftok() này đưa ra cảnh báo với mọi cuộc gọi trừ khi bạn rõ ràng vượt qua cờ để tắt tiếng

Gói này cũng cung cấp

try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
51 để bạn có thể quan sát tần suất ftok() tạo các khóa trùng lặp trên hệ thống của mình

Khởi tạo Semaphore

Khi một semaphore System V được tạo ở cấp độ API C, hệ điều hành không bắt buộc phải khởi tạo giá trị semaphore. (Điều này theo tiêu chuẩn SUSv3 cho

try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
53. ) Một số (hầu hết? tất cả?) Hệ điều hành khởi tạo nó về 0, nhưng hành vi này không chuẩn và do đó không thể dựa vào

Nếu việc tạo semaphore xảy ra theo một cách có trật tự, có thể dự đoán được, thì đây không phải là vấn đề. Nhưng một điều kiện chạy đua phát sinh khi nhiều tiến trình tranh nhau tạo/mở cùng một semaphore. Vấn đề nằm ở chỗ khi một ứng dụng gọi

try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
53 chỉ với cờ
try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
4, người gọi không thể biết liệu anh ta đã tạo một semaphore mới hay đã mở một semaphore hiện có hay chưa. Điều này gây khó khăn cho việc tạo mã đáng tin cậy mà không sử dụng
try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
5. W. Richard Stevens' Lập trình mạng Unix Tập 2 gọi đây là "lỗ hổng chết người trong thiết kế của hệ thống V semaphores" (p 284)

Chẳng hạn, hãy tưởng tượng các quy trình P1 và P2. Họ đang thực thi cùng một mã và mã đó dự định chia sẻ một semaphore nhị phân. Hãy xem xét chuỗi sự kiện sau khi khởi động P1 và P2 –

  1. P1 gọi
    try:
        sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
    except sysv_ipc.ExistentialError:
        # One of my peers created the semaphore already
        sem = sysv_ipc.Semaphore(42)
        # Waiting for that peer to do the first acquire or release
        while not sem.o_time:
            time.sleep(.1)
    else:
        # Initializing sem.o_time to nonzero value
        sem.release()
    # Now the semaphore is safe to use.
    
    57 để tạo semaphore S
  2. P2 gọi
    try:
        sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
    except sysv_ipc.ExistentialError:
        # One of my peers created the semaphore already
        sem = sysv_ipc.Semaphore(42)
        # Waiting for that peer to do the first acquire or release
        while not sem.o_time:
            time.sleep(.1)
    else:
        # Initializing sem.o_time to nonzero value
        sem.release()
    # Now the semaphore is safe to use.
    
    57 để mở S
  3. P1 khởi tạo giá trị của semaphore thành 1
  4. P1 gọi id7, giảm giá trị xuống 0
  5. P2, giả sử S là một semaphore mới được tạo cần được khởi tạo, đặt sai giá trị của semaphore thành 1
  6. P2 gọi id7, giảm giá trị xuống 0. Cả hai quá trình bây giờ nghĩ rằng họ sở hữu khóa

W. Giải pháp của Richard Stevens cho điều kiện chủng tộc này là kiểm tra giá trị của

try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
61 (một phần tử trong cấu trúc
try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
62 được điền trong lệnh gọi tới
try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
63 và được mô-đun này hiển thị với Python) được khởi tạo bằng 0 khi semaphore được tạo và

Trong Python, mỗi quy trình sẽ chạy như thế này

try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.

Khởi tạo bộ nhớ dùng chung

Với bộ nhớ dùng chung, việc sử dụng cờ

try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
4 mà không có
try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
5 là một vấn đề trừ khi bạn biết kích thước của phân đoạn mà bạn có khả năng mở

Tại sao? . Tuy nhiên, khi mở một phân khúc hiện có, 0 là giá trị an toàn được đảm bảo duy nhất (một lần nữa, giả sử một người không biết trước kích thước của phân khúc). Vì

try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
4 có thể mở hoặc tạo phân đoạn nên không có giá trị an toàn cho kích thước trong trường hợp này

Là một (loại) lưu ý phụ, thông số kỹ thuật SUSv3 cho sysv_ipc7 chỉ nói rằng kích thước của một phân đoạn mới không được nhỏ hơn "mức tối thiểu do hệ thống áp đặt". Tôi thu thập được rằng tại một thời điểm, một số hệ thống đặt mức tối thiểu bằng 0 mặc dù thực tế là việc tạo phân đoạn bộ nhớ dùng chung có độ dài bằng 0 không có ý nghĩa gì nhiều. Tôi nghĩ rằng hầu hết các hệ thống hiện đại đều làm điều hợp lý và nhấn mạnh vào độ dài tối thiểu là 1

Giới hạn hàng đợi tin nhắn

Các lập trình viên Python thường có thể không biết gì về các vấn đề cấp phát bộ nhớ. Thật không may, sự kết hợp của các yếu tố khiến chúng trở nên phù hợp khi xử lý hàng đợi tin nhắn của Hệ thống V

Một số triển khai áp đặt các giới hạn cực kỳ keo kiệt. Chẳng hạn, nhiều hệ thống BSDish (macOS, FreeBSD, NetBSD và OpenBSD) giới hạn hàng đợi ở mức 2048 byte. Lưu ý rằng đó là tổng kích thước hàng đợi, không phải kích thước thư. Hai tin nhắn 1k sẽ lấp đầy hàng đợi

Những giới hạn đó có thể rất khó thay đổi. Tốt nhất, chỉ các quy trình đặc quyền mới có thể tăng giới hạn. Tệ nhất, giới hạn là một tham số kernel và yêu cầu thay đổi kernel thông qua điều chỉnh hoặc biên dịch lại

Mô-đun này không thể tìm ra các giới hạn là gì, vì vậy nó không thể đệm chúng hoặc thậm chí báo cáo chúng cho bạn. Trên một số hệ thống, các giới hạn được thể hiện trong tệp tiêu đề, trên các hệ thống khác, chúng có sẵn thông qua giao diện nhân (như FreeBSD's

try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
74). Trong macOS và ở một mức độ nào đó OpenSolaris, tôi không thể tìm ra nơi chúng được xác định và những gì tôi báo cáo ở đây là kết quả của thử nghiệm và phỏng đoán có giáo dục được hình thành bởi Google

Tin vui là mô-đun này sẽ vẫn hoạt động như quảng cáo cho dù các giới hạn này là bao nhiêu. Tuy nhiên, bạn có thể ngạc nhiên khi lệnh gọi tới ____0_______75 bị kẹt vì hàng đợi đã đầy mặc dù bạn chỉ đặt 2048 byte thư trong đó

Dưới đây là các giới hạn tôi có thể tìm thấy trong các hệ điều hành thử nghiệm của mình, được sắp xếp từ tốt nhất (hào phóng nhất) đến tệ nhất (keo kiệt nhất). Thông tin này là hiện tại kể từ năm 2009 khi tôi viết mã hàng đợi tin nhắn. Bây giờ nó đang trở nên khá cũ kỹ. Tôi hy vọng tình hình đã được cải thiện qua những con số năm 2009 mà tôi mô tả dưới đây

Theo OpenSolaris 2008. 05 kích thước tối đa của mỗi hàng đợi mặc định là 64k. Một quá trình đặc quyền (e. g. root) có thể thay đổi điều này thông qua thuộc tính

try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
76 của đối tượng
try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
77. Tôi đã có thể tăng nó lên 16 triệu và gửi thành công 16 tin nhắn 1 triệu vào hàng đợi

Trong Ubuntu 8. 04 (và có lẽ các Linux khác) kích thước tối đa của mỗi hàng đợi mặc định là 16k. Như với OpenSolaris, tôi có thể tăng con số này lên 16 triệu, nhưng chỉ dành cho một quy trình đặc quyền

Trong FreeBSD 7 và tôi nghĩ NetBSD và OpenBSD, kích thước tối đa của mỗi hàng đợi mặc định là 2048 byte. Hơn nữa, một người có thể (với quyền root) đặt

try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
76 thành thứ gì đó lớn hơn và FreeBSD không phàn nàn, nhưng nó cũng bỏ qua thay đổi

macOS là thứ tồi tệ nhất trong số rất nhiều. Mỗi hàng đợi được giới hạn ở 2048 byte và macOS âm thầm bỏ qua các nỗ lực để tăng điều này (giống như FreeBSD). Để tăng thêm sự xúc phạm cho thương tích, dường như không có cách nào để tăng giới hạn này nếu không biên dịch lại kernel. Tôi đoán điều này dựa trên giới hạn hàng đợi tin nhắn Darwin

Nếu bạn muốn tìm kiếm các giới hạn này trên hệ điều hành của mình, các hằng số chính là

try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
79,
try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
80,
try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
81,
try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
82,
try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
83 và
try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
84. Theo BSD,
try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
85 sẽ cho bạn biết những gì bạn cần biết và có thể cho phép bạn thay đổi các thông số này

Không ai thích một ông. Lộn xộn

Semaphores và đặc biệt là bộ nhớ dùng chung hơi khác một chút so với hầu hết các đối tượng Python và do đó, người lập trình cần cẩn thận hơn một chút. Khi một chương trình tạo một semaphore hoặc đối tượng bộ nhớ dùng chung, nó sẽ tạo ra một thứ nằm ngoài quy trình của chính nó, giống như một tệp trên ổ cứng. Nó sẽ không biến mất khi quá trình của bạn kết thúc trừ khi bạn xóa nó một cách rõ ràng

Tóm lại, hãy nhớ dọn dẹp sau khi chính mình

Tham khảo trang địa phương của bạn
try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
86

Mô-đun sysv_ipc chỉ là một trình bao bọc xung quanh API của hệ thống của bạn. Nếu việc triển khai hệ thống của bạn có những điểm kỳ quặc, thì các trang

try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
86 dành cho
try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
88 và
try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
89 có thể sẽ đề cập đến chúng

Công cụ thú vị

Nhiều hệ thống (mặc dù không phải một số phiên bản OS X cũ hơn) đi kèm với

try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
90 và
try:
    sem = sysv_ipc.Semaphore(42, sysv_ipc.IPC_CREX)
except sysv_ipc.ExistentialError:
    # One of my peers created the semaphore already
    sem = sysv_ipc.Semaphore(42)
    # Waiting for that peer to do the first acquire or release
    while not sem.o_time:
        time.sleep(.1)
else:
    # Initializing sem.o_time to nonzero value
    sem.release()
# Now the semaphore is safe to use.
91. Cái trước hiển thị bộ nhớ dùng chung, semaphores và hàng đợi tin nhắn hiện có trên hệ thống của bạn và cái sau cho phép bạn xóa chúng

Cuối cùng nhưng không kém phần quan trọng

Dành cho Pythonistas –

lỗi đã biết

Lỗi? . Tuy nhiên, có một số bất thường dưới mức tối ưu

Các tính năng/Thay đổi trong tương lai

Đây là những tính năng có thể được thêm hoặc không tùy thuộc vào độ khó kỹ thuật, sở thích của người dùng, v.v.

Bộ nhớ dùng chung trong IPC là gì?

Bộ nhớ dùng chung là bộ nhớ được chia sẻ giữa hai hoặc nhiều tiến trình . Mỗi quá trình có không gian địa chỉ riêng của mình; .

Cái nào là ví dụ về bộ nhớ dùng chung?

Với bộ nhớ dùng chung, một chương trình ghi vào bộ nhớ dùng chung bất kỳ dữ liệu nào mà nó cần một chương trình khác để nhận. Ví dụ: nếu Chương trình A muốn cung cấp một danh sách cho Chương trình B, thì nó sẽ lưu dữ liệu vào bộ nhớ dùng chung và đánh dấu nó bằng một semaphore hoặc hệ thống gắn cờ khác để báo hiệu rằng nó đã sẵn sàng để đọc . .

Các quy trình Python có thể chia sẻ bộ nhớ không?

Bộ nhớ dùng chung có thể là một cách rất hiệu quả để xử lý dữ liệu trong một chương trình sử dụng đồng thời. Mmap của Python sử dụng bộ nhớ dùng chung để chia sẻ hiệu quả lượng lớn dữ liệu giữa nhiều quy trình, luồng và tác vụ Python đang diễn ra đồng thời .

Đa xử lý có chia sẻ bộ nhớ không?

shared_memory — Bộ nhớ dùng chung để truy cập trực tiếp giữa các quy trình . Mới trong phiên bản 3. 8. Mô-đun này cung cấp một lớp, SharedMemory, để phân bổ và quản lý bộ nhớ dùng chung được truy cập bởi một hoặc nhiều quy trình trên máy đa xử lý hoặc đa xử lý đối xứng (SMP).