# Threading library
## `import threading`
This is a library that allows us to sequence when we want certain commands and functions to occur
This allows us to do several function calls concurrently (this is because of the global python lock preventing all of the threads from operating at once)
### `threading.active_count()`
This shows you how many threads you currently have that are active
### `threading.current_thread()`
This returns the current thread object in the function where this has been called
### `threading.enumerate()`
Returns a list of all the Thread objects that are currently alive
### `threading.main_thread()`
Returns the main Thread object
### threading.TIMEOUT_MAX
This is a constant that threading has - this is the maximum value allowed for the timeout parameter of blocking functions
* if you specify a timeout greater than this value, then it will raise an Overflow Error
## Thread-Local Data
This is data whose values are thread specific - creates an instance of local and stores adn attributes it
`threading.local` - this is the class that represetnts thread-local data
## Thread Objects
Thread class represents activity that is run in a separate thread of control
We can call a thread's `join()` menhod - this blocks the calling thread until the thread whose `join()` method is called is terminated
### `wait_for(predicate, timeout=None)`
This will wait until a condition evaluates to be true
The predicate should be callable - the result will be interpreted as a boolean value
## Timer Objects
These are started and can be stopped before the action has begun if you call the cancel method.
These timers are started by calling their `start()` method
An example of their use is shown in the example below
```
def hello():
print('Hello World')
t = Timer(30.0, hello)
# After 30 seconds, Hello World will be printed to terminal
t.start()
```