Skip to content

Instantly share code, notes, and snippets.

@pganssle
Last active August 16, 2018 18:48
Show Gist options
  • Save pganssle/5946a1b7120f1c24f97b263878dccfbb to your computer and use it in GitHub Desktop.
Save pganssle/5946a1b7120f1c24f97b263878dccfbb to your computer and use it in GitHub Desktop.
#![feature(concat_idents,duration_as_u128)]
extern crate pyo3;
use std::thread;
use std::time;
use pyo3::prelude::*;
use pyo3::ffi::*;
use std::ffi::CString;
fn import_capsule(thread: i32, call: i32) {
println!("Importing capsule ({}, {})", thread, call);
let PyDateTime_CAPSULE_NAME = CString::new("_curses._C_API").unwrap();
unsafe {
PyCapsule_Import(PyDateTime_CAPSULE_NAME.as_ptr(), 0);
}
println!("Imported ({}, {})", thread, call);
}
fn sleep_import(thread: i32, call: i32) {
println!("GIL Acquisition: ({}, {})", thread, call);
let gil = Python::acquire_gil();
let py = gil.python();
thread::sleep(time::Duration::from_millis(100));
import_capsule(thread, call);
}
fn main() {
let now = time::Instant::now();
let mut handles = Vec::new();
for _thread in 8..10 {
println!("Spawning thread {}", _thread);
let handle = thread::spawn(move || {
for _call in 0..1 {
println!("Starting datetime call {} from thread {}", _thread, _call);
sleep_import(_thread, _call);
// let dt = make_datetime();
println!("Finished call {}", _call);
}
});
handles.push(handle);
}
for handle in handles.into_iter() {
handle.join().unwrap();
}
println!("Done in {}us", now.elapsed().as_micros())
// Result:
// ----------------
// Spawning thread 8
// Spawning thread 9
// Starting datetime call 9 from thread 0
// GIL Acquisition: (9, 0)
// Starting datetime call 8 from thread 0
// GIL Acquisition: (8, 0)
// Acquiring GIL
// Acquired!
// Acquiring GIL
// Importing capsule (9, 0)
// Acquired!
// Importing capsule (8, 0)
// Imported (9, 0)
// Releasing GIL!
// Released!
// Finished call 0
// Imported (8, 0)
// Releasing GIL!
// Released!
// Finished call 0
// Done in 222683us
/// And if you comment out the PyCapsule_Import line:
/// Commenting out the PyCapsule_Import line:
// Spawning thread 8
// Spawning thread 9
// Starting datetime call 8 from thread 0
// GIL Acquisition: (8, 0)
// Starting datetime call 9 from thread 0
// GIL Acquisition: (9, 0)
// Acquiring GIL
// Acquired!
// Acquiring GIL
// Importing capsule (8, 0)
// Imported (8, 0)
// Releasing GIL!
// Acquired!
// Released!
// Finished call 0
// Importing capsule (9, 0)
// Imported (9, 0)
// Releasing GIL!
// Released!
// Finished call 0
// Done in 221164us
}
#![feature(concat_idents,duration_as_u128)]
extern crate pyo3;
use std::thread;
use std::time;
use pyo3::prelude::*;
use pyo3::ffi::*;
fn make_datetime() -> Py<PyDateTime> {
let gil = Python::acquire_gil();
let py = gil.python();
println!("Datetime acquiring gil");
let rv = PyDateTime::new(py, 2011, 1, 1, 0, 0, 0, 0, None).unwrap();
println!("Datetime releasing gil");
rv
}
fn main() {
let now = time::Instant::now();
let mut handles = Vec::new();
for _thread in 0..2 {
println!("Spawning thread {}", _thread);
let handle = thread::spawn(move || {
for _call in 0..2 {
println!("Starting datetime call {} from thread {}", _thread, _call);
let dt = make_datetime();
println!("Finished call {}", _call);
}
});
handles.push(handle);
}
for handle in handles.into_iter() {
handle.join().unwrap();
}
println!("Done in {}us", now.elapsed().as_micros())
// Result:
// ----------------
// Spawning thread 0
// Spawning thread 1
// Starting datetime call 0 from thread 0
// Starting datetime call 1 from thread 0
// Acquiring GIL
// Acquired!
// Datetime acquiring gil
// Importing datetime!
// Acquiring GIL
// Acquired!
// Datetime acquiring gil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment