Example Code : Shared Memory with Mutex (pywin32 and ctypes)

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Srijit Kumar Bhadra

    #1

    Example Code : Shared Memory with Mutex (pywin32 and ctypes)

    Hello,
    Here is some sample code with pywin32 build 203 and ctypes 0.9.6.

    Best regards,
    /Srijit

    File: SharedMemCreate _Mutex_win32all .py

    # This application should be used with SharedMemAccess _Mutex_ctypes.p y
    or SharedMemAccess _Mutex_win32all .py
    #~ a) Creates a shared memory
    #~ b) Creates or Opens a mutex
    #~ c) Reads the contents (null terminated string) of shared memory
    #~ d) Acquires a mutex and then writes a null terminated string to the
    shared memory
    #~ e) Sleeps upto 2 seconds. Sleep time is generated by a random number
    #~ f) Repeats steps (c), (d) and (e) indefintely

    import mmap, random, time
    import win32event, pywintypes, win32api

    def main():
    SHMEMSIZE = 256

    ERROR_ALREADY_E XISTS = 183

    szName = "MyFileMappingO bject"
    szMsg1 = "Message from first process using win32all and mmap - "
    szMutex = "MyMutexObj ect"

    shmem = mmap.mmap(0, SHMEMSIZE, szName, mmap.ACCESS_WRI TE)

    try:
    hMutex = win32event.Crea teMutex(None, pywintypes.FALS E,
    szMutex)
    if (win32api.GetLa stError() == ERROR_ALREADY_E XISTS):
    print"Opened existing mutex object", szMutex
    else:
    print "Created new mutex"

    i=0
    random.seed()
    while 1:
    szMsg1 = szMsg1 + hex(i) + "\0"
    if (len(szMsg1) > SHMEMSIZE):
    print "Current size of string message is", len(szMsg1),
    "and greater than", SHMEMSIZE
    break
    shmem_read = shmem.read(SHME MSIZE)
    shmem_read = shmem_read.rstr ip(chr(0))
    shmem_read = shmem_read.rstr ip(" ")
    print "RECEIVED from SECOND Process: ", shmem_read
    shmem.seek(0)
    wait_result = win32event.Wait ForSingleObject (hMutex, 1000)
    if (wait_result == win32event.WAIT _OBJECT_0):
    shmem.write(szM sg1)
    while (shmem.tell() != SHMEMSIZE):
    shmem.write_byt e(" ")
    shmem.seek(0)
    print "WROTE in FIRST process: ", szMsg1
    win32event.Rele aseMutex(hMutex )
    elif(wait_resul t == win32event.WAIT _TIMEOUT):
    print "COULD NOT ACQUIRE MUTEX. TIMEOUT OCCURED"
    elif (wait_result == win32event.WAIT _ABONDONED):
    print "WAIT ABANDONED"
    i = i + 1
    szMsg1 = "Message from first process using win32all and
    mmap - "
    time.sleep(rand om.random()*2)

    except pywintypes.erro r, (errno, object, strerror):
    print "Error in", object, ":", strerror

    if __name__ == "__main__":
    main()


    File: SharedMemCreate _Mutex_ctypes.p y

    # This application should be used with SharedMemAccess _Mutex_ctypes.p y
    or SharedMemAccess _Mutex_win32all .py
    #~ a) Creates a shared memory
    #~ b) Creates or Opens a mutex
    #~ c) Reads the contents (null terminated string) of shared memory
    #~ d) Acquires a mutex and then writes a null terminated string to the
    shared memory
    #~ e) Sleeps upto 2 seconds. Sleep time is generated by a random number
    #~ f) Repeats steps (c), (d) and (e) indefintely


    # There are two options to implement this code - Option A or Option B.
    If Option B(A) is chosen then
    # Option A(B) should be commented.
    import random, time
    from ctypes import *

    def main():
    try:
    SHMEMSIZE = 256

    TRUE = 1
    FALSE = 0
    ERROR_ALREADY_E XISTS = 183
    FILE_MAP_ALL_AC CESS = 0xF001F
    WAIT_OBJECT_0 = 0
    WAIT_TIMEOUT = 0x102
    WAIT_ABANDONED = 0x80
    PAGE_READWRITE = 0x04
    INVALID_HANDLE_ VALUE = 0xFFFFFFFF

    szName = "MyFileMappingO bject"
    szMsg1 = "Message from first process using ctypes - "
    szMutex = "MyMutexObj ect"

    hMutex = windll.kernel32 .CreateMutexA(N one, FALSE, szMutex)
    if (hMutex == 0):
    raise WinError()
    elif (windll.kernel3 2.GetLastError( ) == ERROR_ALREADY_E XISTS):
    print"Opened existing mutex object", szMutex
    else:
    print "Created new mutex"

    hMap = windll.kernel32 .CreateFileMapp ingA(INVALID_HA NDLE_VALUE,
    None, PAGE_READWRITE, 0, SHMEMSIZE, szName)
    if (hMap == 0):
    print "Could not open file mapping object"
    raise WinError()

    MapViewOfFile = windll.kernel32 .MapViewOfFile
    MapViewOfFile.r estype = POINTER(c_char) # Option A
    pBuf = MapViewOfFile(h Map, FILE_MAP_ALL_AC CESS, 0, 0, 0)
    if (pBuf == 0):
    raise WinError()

    i=0
    random.seed()
    while 1:
    szMsg1 = szMsg1 + hex(i) + "\0"
    pBuf_str = cast(pBuf, c_char_p) # Option A
    if (len(szMsg1) > SHMEMSIZE):
    print "Current size of string message is", len(szMsg1),
    "and greater than", SHMEMSIZE
    break
    print "RECEIVED from SECOND Process: ", pBuf_str.value #
    Option A
    #~ print "RECEIVED from SECOND Process: ", string_at(pBuf)
    # Option B
    wait_result = windll.kernel32 .WaitForSingleO bject(hMutex,
    1000)
    if (wait_result == WAIT_OBJECT_0):
    memset(pBuf, ord(" "), SHMEMSIZE)
    cdll.msvcrt.str cpy(pBuf_str, szMsg1) # Option A
    #~ cdll.msvcrt.str cpy(pBuf, szMsg1) # Option B
    print "WROTE in FIRST process: ", szMsg1
    release_mutex = windll.kernel32 .ReleaseMutex(h Mutex)
    if (release_mutex == 0):
    print "CANNOT RELEASE ACQUIRED MUTEX"
    elif(wait_resul t == WAIT_TIMEOUT):
    print "COULD NOT ACQUIRE MUTEX. TIMEOUT OCCURED"
    elif (wait_result == WAIT_ABONDONED) :
    print "WAIT ABANDONED"
    i = i + 1
    szMsg1 = "Message from first process using ctypes - "
    time.sleep(rand om.random()*2)

    windll.kernel32 .UnmapViewOfFil e(pBuf)
    windll.kernel32 .CloseHandle(hM ap)
    return
    except WindowsError, (strerror):
    print strerror
    if (pBuf != 0):
    windll.kernel32 .UnmapViewOfFil e(pBuf)
    if (hMap != 0):
    windll.kernel32 .CloseHandle(hM ap)
    return

    if __name__ == "__main__":
    main()


    File : SharedMemAccess _Mutex_win32all .py

    # This application should be used with SharedMemCreate _Mutex_ctypes.p y
    or SharedMemCreate _Mutex_win32all .py
    #~ a) Opens an existing shared memory
    #~ b) Opens an existing mutex
    #~ c) Reads the contents (null terminated string) of shared memory
    #~ d) Acquires a mutex and then writes a null terminated string to the
    shared memory
    #~ e) Sleeps upto 2 seconds. Sleep time is generated by a random number
    #~ f) Repeats steps (c), (d) and (e) indefintely

    import mmap, random, time
    import win32event, pywintypes

    def main():
    SHMEMSIZE = 256

    STANDARD_RIGHTS _REQUIRED = 0xF0000
    SYNCHRONIZE = 0x100000
    MUTANT_QUERY_ST ATE = 0x1

    MUTEX_ALL_ACCES S = STANDARD_RIGHTS _REQUIRED | SYNCHRONIZE |
    MUTANT_QUERY_ST ATE

    szName = "MyFileMappingO bject"
    szMsg1 = "Message from second process using win32all and mmap - "
    szMutex = "MyMutexObj ect"

    shmem = mmap.mmap(0, SHMEMSIZE, szName, mmap.ACCESS_WRI TE)
    try:
    hMutex = win32event.Open Mutex(MUTEX_ALL _ACCESS,
    pywintypes.FALS E, szMutex)
    print"Opened existing mutex object", szMutex
    i = 0;
    random.seed()
    while 1:
    szMsg1 = szMsg1 + hex(i) + "\0"
    if (len(szMsg1) > SHMEMSIZE):
    print "Current size of string message is", len(szMsg1),
    "and greater than", SHMEMSIZE
    break
    shmem_read = shmem.read(SHME MSIZE)
    shmem_read = shmem_read.rstr ip(chr(0))
    shmem_read = shmem_read.rstr ip(" ")
    print "RECEIVED from FIRST Process: ", shmem_read
    shmem.seek(0)
    wait_result = win32event.Wait ForSingleObject (hMutex, 1000)
    if (wait_result == win32event.WAIT _OBJECT_0):
    shmem.write(szM sg1)
    while (shmem.tell() != SHMEMSIZE):
    shmem.write_byt e(" ")
    shmem.seek(0)
    print "WROTE in SECOND process: ", szMsg1
    win32event.Rele aseMutex(hMutex )
    elif(wait_resul t == win32event.WAIT _TIMEOUT):
    print "COULD NOT ACQUIRE MUTEX. TIMEOUT OCCURED"
    elif (wait_result == win32event.WAIT _ABONDONED):
    print "WAIT ABANDONED"
    i = i + 1
    szMsg1 = "Message from second process using win32all and
    mmap - "
    time.sleep(rand om.random()*2)
    except pywintypes.erro r, (errno, object, strerror):
    print "Error in", object, ":", strerror

    shmem.close()
    return


    if __name__ == "__main__":
    main()


    File: SharedMemAccess _Mutex_ctypes.p y

    # This application should be used with SharedMemCreate _Mutex_ctypes.p y
    or SharedMemCreate _Mutex_win32all .py
    #~ a) Opens an existing shared memory
    #~ b) Opens an existing mutex
    #~ c) Reads the contents (null terminated string) of shared memory
    #~ d) Acquires a mutex and then writes a null terminated string to the
    shared memory
    #~ e) Sleeps upto 2 seconds. Sleep time is generated by a random number
    #~ f) Repeats steps (c), (d) and (e) indefintely


    # There are two options to implement this code - Option A or Option B.
    If Option B(A) is chosen then
    # Option A(B) should be commented.
    import random, time
    from ctypes import *

    def main():

    SHMEMSIZE = 256

    FILE_MAP_ALL_AC CESS = 0xF001F
    STANDARD_RIGHTS _REQUIRED = 0xF0000
    SYNCHRONIZE = 0x100000
    MUTANT_QUERY_ST ATE = 0x1
    MUTEX_ALL_ACCES S = STANDARD_RIGHTS _REQUIRED | SYNCHRONIZE |
    MUTANT_QUERY_ST ATE
    WAIT_OBJECT_0 = 0
    WAIT_TIMEOUT = 0x102
    WAIT_ABANDONED = 0x80
    TRUE = 1
    FALSE = 0

    szName = "MyFileMappingO bject"
    szMsg1 = "Message from second process using ctypes - "
    szMutex = "MyMutexObj ect"

    hMap = 0
    pBuf = 0
    hMutex = 0

    try:
    hMap = windll.kernel32 .OpenFileMappin gA(FILE_MAP_ALL _ACCESS,
    FALSE, szName)
    if (hMap == 0):
    raise WinError()

    MapViewOfFile = windll.kernel32 .MapViewOfFile
    MapViewOfFile.r estype = POINTER(c_char) # Option A
    pBuf = MapViewOfFile(h Map, FILE_MAP_ALL_AC CESS, 0, 0, 0)
    if (pBuf == 0):
    raise WinError()

    hMutex = windll.kernel32 .OpenMutexA(MUT EX_ALL_ACCESS, FALSE,
    szMutex)
    if (hMutex == 0):
    raise WinError()
    else:
    print"Opened existing mutex object", szMutex

    i=0
    random.seed()
    while 1:
    szMsg1 = szMsg1 + hex(i) + "\0"
    pBuf_str = cast(pBuf, c_char_p) # Option A
    if (len(szMsg1) > SHMEMSIZE):
    print "Current size of string message is", len(szMsg1),
    "and greater than", SHMEMSIZE
    break
    print "RECEIVED from FIRST Process: ", pBuf_str.value #
    Option A
    #~ print "RECEIVED from FIRST Process: ", string_at(pBuf) #
    Option B
    wait_result = windll.kernel32 .WaitForSingleO bject(hMutex,
    1000)
    if (wait_result == WAIT_OBJECT_0):
    memset(pBuf, ord(" "), SHMEMSIZE)
    cdll.msvcrt.str cpy(pBuf_str, szMsg1) # Option A
    #~ cdll.msvcrt.str cpy(pBuf, szMsg1) # Option B
    print "WROTE in SECOND process: ", szMsg1
    release_mutex = windll.kernel32 .ReleaseMutex(h Mutex)
    if (release_mutex == 0):
    print "CANNOT RELEASE ACQUIRED MUTEX"
    elif(wait_resul t == WAIT_TIMEOUT):
    print "COULD NOT ACQUIRE MUTEX. TIMEOUT OCCURED"
    elif (wait_result == WAIT_ABONDONED) :
    print "WAIT ABANDONED"
    i = i + 1
    szMsg1 = "Message from second process using ctypes - "
    time.sleep(rand om.random()*2)

    windll.kernel32 .UnmapViewOfFil e(pBuf)
    windll.kernel32 .CloseHandle(hM ap)
    return
    except WindowsError, (strerror):
    print strerror
    if (pBuf != 0):
    windll.kernel32 .UnmapViewOfFil e(pBuf)
    if (hMap != 0):
    windll.kernel32 .CloseHandle(hM ap)
    return

    if __name__ == "__main__":
    main()

Working...