python - Storing strings in a multiprocessing sharedctypes Array -


i trying share strings between processes using sharedctypes part of multiprocessing module.

tl;dr: wish put strings sharedctypes array, so:

from multiprocessing.sharedctypes import array  array(ctypes.c_char, ['a string', 'another string']) 

more information:

the docs have note:

"note array of ctypes.c_char has value , raw attributes allow 1 use store , retrieve strings."

using c_char alone:

from multiprocessing.sharedctypes import array  array(ctypes.c_char, ['a string', 'another string']) 

i type error, makes sense:

typeerror: 1 character bytes, bytearray or integer expected 

this can (kind of) work splittingthe sting in bytes (which makes sense):

from multiprocessing.sharedctypes import array  multiproccessing.sharedctypes.array(ctypes.c_char, [b's', b't', b'r', b'i', b'n', b'g']) 

but not convenient storing large lists of strings.

however when tried using value , raw attributes shown in docs here , mentioned in note there still no magic:

array(ctypes.c_char.value, ['string']) 

gives error:

typeerror: unsupported operand type(s) *: 'getset_descriptor' , 'int' 

and raw gives this:

array(ctypes.c_char.raw, ['string'])  attributeerror: type object 'c_char' has no attribute 'raw' 

i have tried using c_wchar_p type in table of primitive c compatible data types (found in docs) corresponds directly string:

 array(ctypes.c_wchar_p, ['string']) 

this crashes python, no error code reported, process exits code 0.

why can't sharedctypes arrays hold pointers c_wchar_p type? other solution or advice on how store strings in sharedctype arrays welcome!

update - code occasionally works (most of time python stops working strings back, although gibberish). comments mention working fine on windows.

from multiprocessing import process, lock multiprocessing.sharedctypes import value, array import ctypes   def print_strings(s):     """print strings in c array"""     print([a in s])  if __name__ == '__main__':     lock = lock()     string_array = array(ctypes.c_wchar_p, ['string'])     q = process(target=print_strings, args=(string_array,))     q.start()     q.join() 

update 2

this gibberish get:

['汣獵癩汥⁹景椠瑮搠祴数\u2e73ਊ††敓\u2065汁潳\u200a†ⴠⴭⴭⴭਭ††捳灩\u2e79灳捥慩\u2e6c癩\u202c捳灩\u2e79灳捥慩\u2e6c癩\u0a65\u200a†丠瑯獥\u200a†ⴠⴭⴭ\u200a†圠\u2065獵\u2065桴\u2065污潧楲桴\u206d異汢獩敨\u2064祢䌠敬獮慨⁷ㅛ彝愠摮爠晥牥湥散\u2064祢\u200a†䄠牢浡睯瑩⁺湡\u2064瑓来湵嬠崲\u2c5f映牯眠楨档琠敨映湵瑣潩\u206e潤慭湩椠ੳ††慰瑲瑩潩敮\u2064湩潴琠敨琠潷椠瑮牥慶獬嬠ⰰ崸愠摮⠠ⰸ湩⥦\u202c湡\u2064桃扥獹敨\u0a76††潰祬潮業污攠灸湡楳湯\u2073牡\u2065浥汰祯摥椠\u206e慥档椠瑮牥慶\u2e6c删汥瑡癩\u2065牥潲\u2072湯\u200a†琠敨搠浯楡\u206eせ㌬崰甠楳杮䤠䕅⁅牡瑩浨瑥捩椠\u2073潤畣敭瑮摥嬠崳\u205f獡栠癡湩\u2067\u0a61††数歡漠\u2066⸵攸ㄭ‶楷桴愠\u206e浲\u2073景ㄠ㐮ⵥ㘱⠠\u206e‽〳〰⤰ਮ\u200a†删晥牥湥散ੳ††ⴭⴭⴭⴭⴭ\u200a†⸠\u202eㅛ⁝\u2e43圠\u202e汃湥桳睡\u202c䌢敨祢桳癥猠牥敩\u2073潦\u2072慭桴浥瑡捩污映湵瑣潩獮Ⱒ椠੮†††††⨠慎楴湯污倠票楳慣\u206c慌潢慲潴祲䴠瑡敨慭楴慣\u206c慔汢獥Ⱚ瘠汯\u202eⰵ䰠湯潤㩮\u200a†††††效\u2072慍敪瑳❹\u2073瑓瑡潩敮祲传晦捩ⱥㄠ㘹⸲\u200a†⸠\u202e㉛⁝\u2e4d䄠牢浡睯瑩⁺湡\u2064\u2e49䄠\u202e瑓来湵\u202c䠪湡扤潯\u206b景䴠瑡敨慭楴慣੬†††††䘠湵瑣潩獮Ⱚㄠ琰\u2068牰湩楴杮\u202c敎⁷潙歲›潄敶Ⱳㄠ㘹ⰴ瀠\u2e70㌠㤷ਮ†††††栠瑴㩰⼯睷\u2e77慭桴献畦挮⽡捾浢愯湡獤瀯条彥㜳⸹瑨੭††⸮嬠崳栠瑴㩰⼯潫敢敳牡档挮慰\u2e6e牯⽧瑨潤獣䴯瑡\u2d68敃桰獥䴯瑡⽨敃桰獥栮浴੬\u200a†䔠慸灭敬ੳ††ⴭⴭⴭⴭ\u200a†㸠㸾渠\u2e70ど嬨⸰⥝\u200a†愠牲祡ㄨ〮\u0a29††㸾‾灮椮⠰せⰮㄠ\u202e\u202b樲⥝\u200a†愠牲祡嬨ㄠ〮〰〰〰⬰⸰\u206a†††Ⱐ†⸰㠱㠷㌵㌷〫㘮㘴㘱㐹樴⥝ਊ††', 'ਊ††敓\u2065汁潳\u200a†ⴠⴭⴭⴭਭ††捳灩\u2e79灳捥慩\u2e6c癩\u202c捳灩\u2e79灳捥慩\u2e6c癩\u0a65\u200a†丠瑯獥\u200a†ⴠⴭⴭ\u200a†圠\u2065獵\u2065桴\u2065污潧楲桴\u206d異汢獩敨\u2064祢䌠敬獮慨⁷ㅛ彝愠摮爠晥牥湥散\u2064祢\u200a†䄠牢浡睯瑩⁺湡\u2064瑓来湵嬠崲\u2c5f映牯眠楨档琠敨映湵瑣潩\u206e潤慭湩椠ੳ††慰瑲瑩潩敮\u2064湩潴琠敨琠潷椠瑮牥慶獬嬠ⰰ崸愠摮⠠ⰸ湩⥦\u202c湡\u2064桃扥獹敨\u0a76††潰祬潮業污攠灸湡楳湯\u2073牡\u2065浥汰祯摥椠\u206e慥档椠瑮牥慶\u2e6c删汥瑡癩\u2065牥潲\u2072湯\u200a†琠敨搠浯楡\u206eせ㌬崰甠楳杮䤠䕅⁅牡瑩浨瑥捩椠\u2073潤畣敭瑮摥嬠崳\u205f獡栠癡湩\u2067\u0a61††数歡漠\u2066⸵攸ㄭ‶楷桴愠\u206e浲\u2073景ㄠ㐮ⵥ㘱⠠\u206e‽〳〰⤰ਮ\u200a†删晥牥湥散ੳ††ⴭⴭⴭⴭⴭ\u200a†⸠\u202eㅛ⁝\u2e43圠\u202e汃湥桳睡\u202c䌢敨祢桳癥猠牥敩\u2073潦\u2072慭桴浥瑡捩污映湵瑣潩獮Ⱒ椠੮†††††⨠慎楴湯污倠票楳慣\u206c慌潢慲潴祲䴠瑡敨慭楴慣\u206c慔汢獥Ⱚ瘠汯\u202eⰵ䰠湯潤㩮\u200a†††††效\u2072慍敪瑳❹\u2073瑓瑡潩敮祲传晦捩ⱥㄠ㘹⸲\u200a†⸠\u202e㉛⁝\u2e4d䄠牢浡睯瑩⁺湡\u2064\u2e49䄠\u202e瑓来湵\u202c䠪湡扤潯\u206b景䴠瑡敨慭楴慣੬†††††䘠湵瑣潩獮Ⱚㄠ琰\u2068牰湩楴杮\u202c敎⁷潙歲›潄敶Ⱳㄠ㘹ⰴ瀠\u2e70㌠㤷ਮ†††††栠瑴㩰⼯睷\u2e77慭桴献畦挮⽡捾浢愯湡獤瀯条彥㜳⸹瑨੭††⸮嬠崳栠瑴㩰⼯潫敢敳牡档挮慰\u2e6e牯⽧瑨潤獣䴯瑡\u2d68敃桰獥䴯瑡⽨敃桰獥栮浴੬\u200a†䔠慸灭敬ੳ††ⴭⴭⴭⴭ\u200a†㸠㸾渠\u2e70ど嬨⸰⥝\u200a†愠牲祡ㄨ〮\u0a29††㸾‾灮椮⠰せⰮㄠ\u202e\u202b樲⥝\u200a†愠牲祡嬨ㄠ〮〰〰〰⬰⸰\u206a†††Ⱐ†⸰㠱㠷㌵㌷〫㘮㘴㘱㐹樴⥝ਊ††']

(yes apparently came 'string', don't ask me how)

the problem having mentioned in the documentation:

note: although possible store pointer in shared memory remember refer location in address space of specific process. however, pointer quite invalid in context of second process , trying dereference pointer second process may cause crash.

this means storing pointers (like strings) not going work, because address child process, , address not valid anymore there (hence segmentation fault). consider, example, alternative, strings concatenated 1 array , array lengths passed (you can tweak convenience):

from multiprocessing import process, lock multiprocessing.sharedctypes import value, array import ctypes  def print_strings(s, s_len):     """print strings in c array"""     received_strings = []     start = 0     length in s_len:         received_strings.append(s[start:start + length])         start += length     print("received strings:", received_strings)  if __name__ == '__main__':     lock = lock()     my_strings = ['string1', 'str2']     my_strings_len = [len(s) s in my_strings]     string_array = array(ctypes.c_wchar, ''.join(my_strings))     string_len_array = array(ctypes.c_uint, my_strings_len)     q = process(target=print_strings, args=(string_array, string_len_array))     q.start()     q.join() 

output:

received strings: ['string1', 'str2'] 

about addresses in subprocess:

this bit off topic of question, long put comment. starts out of depth, take @ eryksun's comments below more informed insights, here's understanding anyway. on unix(-like) new process created through fork has same memory , (virtual) addresses parent process, if exec program that's not case anymore; don't know if python's multiprocessing runs exec or not on unix (note: see eryksun's comment more on , set_start_method), in case wouldn't assume there guarantee address in python-managed memory pool should stay same. on windows, createprocess makes new process executable not have in principle in common parent. don't think shared libraries used multiple processes (.so/.dll) should @ same address in either platform. don't think sharing (virtual) addresses between processes makes sense when using shared memory since, if recall correctly (and may not), shared memory blocks mapped arbitrary virtual addresses on each process. impression there no reason (or "good , obvious", @ least) share addresses subprocess (of course, pointer types in ctypes still useful talk native libraries within same process).

as said, i'm not 100% confident in this, think general idea goes that.


Comments

Popular posts from this blog

PHP and MySQL WP -

android - InAppBilling registering BroadcastReceiver in AndroidManifest -

go - golang pprof for c library code -