Thread Locking issue - Can't allocate lock (sem_init fail)

MRAB google at mrabarnett.plus.com
Mon Dec 15 10:42:16 EST 2008


Philip Semanchuk wrote:
> 
> On Dec 15, 2008, at 4:56 AM, jamskip at googlemail.com wrote:
> 
>> Hi all,
>>
>> I have a peculiar problem with a multithreaded program of mine
>> (actually I've sort of inherited it). Before i show you the error,
>> here's a litle background. Its a program to check email addresses are
>> valid, and its main task is to verify the domain names.
>>
>> Here's the basic functionality:
>>
>> * The prog has a list of domains it has seen before which is read into
>> memory (the 'rollover').
>> * A new list of emails is read-in from a file (to a queue) and is
>> checked against the rollover.
>> * If we've seen the domain before then update the existing entry.
>> * If we've not seen the domain before, add it.
>>
>> The program is multithreaded to speed up the processing...there are
>> input and output Queues.
>>
>> Now, each domain entry is an class object containing various bits of
>> info. Each domain class also has its own lock, so that only one thread
>> can modify each domain at a time.
>>
>> I'm load-testing the program with a sample of 1 million email
>> addresses and when i hit about the 500,000 mark i get a locking
>> error...
>>
>>    sem_init: No space left on device
>>    Exception in thread Thread-2:
>>    Traceback (most recent call last):
>>      File "/usr/local/lib/python2.4/threading.py", line 442, in
>> __bootstrap
>>        self.run()
>>      File "/usr/local/lib/python2.4/threading.py", line 422, in run
>>        self.__target(*self.__args, **self.__kwargs)
>>      File "jess.py", line 250, in worker
>>        record.result = function( id, record.value )
>>      File "jess.py", line 291, in action
>>        found_domain = domains.addNewDomain( domain_name )
>>      File "jess.py", line 123, in addNewDomain
>>        self.domain_store.append( self.Domain( name = name ) )
>>      File "jess.py", line 46, in __init__
>>        self.lock = Lock()
>>    error: can't allocate lock
>>
>> Googling for this sort of error doesn't yield any results, and i can't
>> find any information about limits to the number of locks you can have
>> in Python. The 'No space left on device' message indicates a memory
>> issue, however i doubt this since its running on a linux server with 4
>> cores and 16GB ram. It seems more like an internal Python limit has
>> been hit (sem_init - semaphore initialisation?). Does anyone know more
>> about threading internals and any internal limits?
> 
> Hi Jamskip,
> I don't work with threading code but I have been working with semaphores 
> for my IPC extensions. sem_init() is a call to create a semaphore 
> (http://linux.die.net/man/3/sem_init). If it is failing, then I'd guess 
> you're trying to create an awful lot of semaphores (intentionally or 
> otherwise) and that you're hitting some internal limit.
> 
> I would not be too quick to assume that the number of semaphores one can 
> create is bounded by the amount of RAM in your system. I don't think 
> they're simple chunks of malloc-ed memory. They're probably represented 
> in a kernel data structure somewhere that's hardcoded to some generous 
> but fixed value.
> 
> Please note that this is all speculation on my part. I think that the 
> Python threading implementation would use the "local" (i.e. not 
> process-shared) semaphores which can be allocated on the process' heap. 
> This would seem only RAM-limited, but I'll bet it isn't.
> 
> You might want to start debugging by track exactly how many locks you're 
> creating. If the number is really big, start investigating kernel 
> semaphore limits and how they're set.
> 
You're creating a thread and a lock for each _domain_? Sounds like 
overkill to me. Many domains means many threads and many locks, by the 
sounds of it too many for the system.



More information about the Python-list mailing list