std::sync::Arc - Rust (original) (raw)

Struct std::sync::Arc1.0.0 [−] [src]

pub struct Arc where
    T: ?Sized,  { /* fields omitted */ }

A thread-safe reference-counting pointer. 'Arc' stands for 'Atomically Reference Counted'.

The type Arc<T> provides shared ownership of a value of type T, allocated in the heap. Invoking clone on Arc produces a new pointer to the same value in the heap. When the last Arcpointer to a given value is destroyed, the pointed-to value is also destroyed.

Shared references in Rust disallow mutation by default, and Arc is no exception: you cannot generally obtain a mutable reference to something inside an Arc. If you need to mutate through an Arc, useMutex, RwLock, or one of the Atomictypes.

Unlike Rc, Arc<T> uses atomic operations for its reference counting This means that it is thread-safe. The disadvantage is that atomic operations are more expensive than ordinary memory accesses. If you are not sharing reference-counted values between threads, consider usingRc for lower overhead. Rc is a safe default, because the compiler will catch any attempt to send an Rc between threads. However, a library might choose Arc<T> in order to give library consumers more flexibility.

Arc<T> will implement Send and Sync as long as the T implementsSend and Sync. Why can't you put a non-thread-safe type T in anArc<T> to make it thread-safe? This may be a bit counter-intuitive at first: after all, isn't the point of Arc<T> thread safety? The key is this: Arc<T> makes it thread safe to have multiple ownership of the same data, but it doesn't add thread safety to its data. ConsiderArc<RefCell>. RefCell isn't Sync, and if Arc<T> was alwaysSend, Arc<RefCell> would be as well. But then we'd have a problem:RefCell is not thread safe; it keeps track of the borrowing count using non-atomic operations.

In the end, this means that you may need to pair Arc<T> with some sort ofstd::sync type, usually Mutex.

The downgrade method can be used to create a non-owningWeak pointer. A Weak pointer can be upgraded to an Arc, but this will return None if the value has already been dropped.

A cycle between Arc pointers will never be deallocated. For this reason,Weak is used to break cycles. For example, a tree could have strong Arc pointers from parent nodes to children, and Weakpointers from children back to their parents.

Creating a new reference from an existing reference counted pointer is done using theClone trait implemented for Arc and Weak.

use std::sync::Arc; let foo = Arc::new(vec![1.0, 2.0, 3.0]);

let a = foo.clone(); let b = Arc::clone(&foo); Run

The Arc::clone(&from) syntax is the most idiomatic because it conveys more explicitly the meaning of the code. In the example above, this syntax makes it easier to see that this code is creating a new reference rather than copying the whole content of foo.

Arc<T> automatically dereferences to T (via the Deref trait), so you can call T's methods on a value of type Arc<T>. To avoid name clashes with T's methods, the methods of Arc<T> itself are associated functions, called using function-like syntax:

use std::sync::Arc; let my_arc = Arc::new(());

Arc::downgrade(&my_arc);Run

Weak does not auto-dereference to T, because the value may have already been destroyed.

Sharing some immutable data between threads:

use std::sync::Arc; use std::thread;

let five = Arc::new(5);

for _ in 0..10 { let five = Arc::clone(&five);

thread::spawn(move || {
    println!("{:?}", five);
});

}Run

Sharing a mutable AtomicUsize:

use std::sync::Arc; use std::sync::atomic::{AtomicUsize, Ordering}; use std::thread;

let val = Arc::new(AtomicUsize::new(5));

for _ in 0..10 { let val = Arc::clone(&val);

thread::spawn(move || {
    let v = val.fetch_add(1, Ordering::SeqCst);
    println!("{:?}", v);
});

}Run

See the rc documentation for more examples of reference counting in general.

impl<T> [Arc](../../std/sync/struct.Arc.html "struct std::sync::Arc")<T>[src]

pub fn [new](#method.new)(data: T) -> [Arc](../../std/sync/struct.Arc.html "struct std::sync::Arc")<T>[src]

Constructs a new Arc<T>.

use std::sync::Arc;

let five = Arc::new(5);Run

pub fn [try_unwrap](#method.try%5Funwrap)(this: [Arc](../../std/sync/struct.Arc.html "struct std::sync::Arc")<T>) -> [Result](../../std/result/enum.Result.html "enum std::result::Result")<T, [Arc](../../std/sync/struct.Arc.html "struct std::sync::Arc")<T>>

1.4.0

[src]

Returns the contained value, if the Arc has exactly one strong reference.

Otherwise, an Err is returned with the same Arc that was passed in.

This will succeed even if there are outstanding weak references.

use std::sync::Arc;

let x = Arc::new(3); assert_eq!(Arc::try_unwrap(x), Ok(3));

let x = Arc::new(4); let _y = Arc::clone(&x); assert_eq!(*Arc::try_unwrap(x).unwrap_err(), 4);Run

`impl Arc where

T: ?Sized, `[src]

pub fn [into_raw](#method.into%5Fraw)(this: [Arc](../../std/sync/struct.Arc.html "struct std::sync::Arc")<T>) -> [*const T](../primitive.pointer.html)

1.17.0

[src]

Consumes the Arc, returning the wrapped pointer.

To avoid a memory leak the pointer must be converted back to an Arc usingArc::from_raw.

use std::sync::Arc;

let x = Arc::new(10); let x_ptr = Arc::into_raw(x); assert_eq!(unsafe { *x_ptr }, 10);Run

pub unsafe fn [from_raw](#method.from%5Fraw)(ptr: [*const T](../primitive.pointer.html)) -> [Arc](../../std/sync/struct.Arc.html "struct std::sync::Arc")<T>

1.17.0

[src]

Constructs an Arc from a raw pointer.

The raw pointer must have been previously returned by a call to aArc::into_raw.

This function is unsafe because improper use may lead to memory problems. For example, a double-free may occur if the function is called twice on the same raw pointer.

use std::sync::Arc;

let x = Arc::new(10); let x_ptr = Arc::into_raw(x);

unsafe {

let x = Arc::from_raw(x_ptr);
assert_eq!(*x, 10);

}

Run

pub fn [downgrade](#method.downgrade)(this: &[Arc](../../std/sync/struct.Arc.html "struct std::sync::Arc")<T>) -> [Weak](../../std/sync/struct.Weak.html "struct std::sync::Weak")<T>

1.4.0

[src]

Creates a new Weak pointer to this value.

use std::sync::Arc;

let five = Arc::new(5);

let weak_five = Arc::downgrade(&five);Run

pub fn [weak_count](#method.weak%5Fcount)(this: &[Arc](../../std/sync/struct.Arc.html "struct std::sync::Arc")<T>) -> [usize](../primitive.usize.html)

1.15.0

[src]

Gets the number of Weak pointers to this value.

This method by itself is safe, but using it correctly requires extra care. Another thread can change the weak count at any time, including potentially between calling this method and acting on the result.

use std::sync::Arc;

let five = Arc::new(5); let _weak_five = Arc::downgrade(&five);

assert_eq!(1, Arc::weak_count(&five));Run

pub fn [strong_count](#method.strong%5Fcount)(this: &[Arc](../../std/sync/struct.Arc.html "struct std::sync::Arc")<T>) -> [usize](../primitive.usize.html)

1.15.0

[src]

Gets the number of strong (Arc) pointers to this value.

This method by itself is safe, but using it correctly requires extra care. Another thread can change the strong count at any time, including potentially between calling this method and acting on the result.

use std::sync::Arc;

let five = Arc::new(5); let _also_five = Arc::clone(&five);

assert_eq!(2, Arc::strong_count(&five));Run

pub fn [ptr_eq](#method.ptr%5Feq)(this: &[Arc](../../std/sync/struct.Arc.html "struct std::sync::Arc")<T>, other: &[Arc](../../std/sync/struct.Arc.html "struct std::sync::Arc")<T>) -> [bool](../primitive.bool.html)

1.17.0

[src]

Returns true if the two Arcs point to the same value (not just values that compare as equal).

use std::sync::Arc;

let five = Arc::new(5); let same_five = Arc::clone(&five); let other_five = Arc::new(5);

assert!(Arc::ptr_eq(&five, &same_five)); assert!(!Arc::ptr_eq(&five, &other_five));Run

`impl Arc where

T: Clone, `[src]

pub fn [make_mut](#method.make%5Fmut)(this: &mut [Arc](../../std/sync/struct.Arc.html "struct std::sync::Arc")<T>) -> [&mut ](../primitive.reference.html)T

1.4.0

[src]

Makes a mutable reference into the given Arc.

If there are other Arc or Weak pointers to the same value, then make_mut will invoke clone on the inner value to ensure unique ownership. This is also referred to as clone-on-write.

See also get_mut, which will fail rather than cloning.

use std::sync::Arc;

let mut data = Arc::new(5);

*Arc::make_mut(&mut data) += 1;
let mut other_data = Arc::clone(&data); *Arc::make_mut(&mut data) += 1;
*Arc::make_mut(&mut data) += 1;
*Arc::make_mut(&mut other_data) *= 2;

assert_eq!(*data, 8); assert_eq!(*other_data, 12);Run

`impl Arc where

T: ?Sized, `[src]

pub fn [get_mut](#method.get%5Fmut)(this: &mut [Arc](../../std/sync/struct.Arc.html "struct std::sync::Arc")<T>) -> [Option](../../std/option/enum.Option.html "enum std::option::Option")<[&mut ](../primitive.reference.html)T>

1.4.0

[src]

Returns a mutable reference to the inner value, if there are no other Arc or Weak pointers to the same value.

Returns None otherwise, because it is not safe to mutate a shared value.

See also make_mut, which will clonethe inner value when it's shared.

use std::sync::Arc;

let mut x = Arc::new(3); *Arc::get_mut(&mut x).unwrap() = 4; assert_eq!(*x, 4);

let _y = Arc::clone(&x); assert!(Arc::get_mut(&mut x).is_none());Run

`impl<T, U> CoerceUnsized<Arc> for Arc where

T: Unsize + ?Sized,
U: ?Sized, `[src]

`impl Sync for Arc where

T: Send + Sync + ?Sized, `[src]

impl<T> [From](../../std/convert/trait.From.html "trait std::convert::From")<T> for [Arc](../../std/sync/struct.Arc.html "struct std::sync::Arc")<T>

1.6.0

[src]

impl<'a> [From](../../std/convert/trait.From.html "trait std::convert::From")<&'a [str](../primitive.str.html)> for [Arc](../../std/sync/struct.Arc.html "struct std::sync::Arc")<[str](../primitive.str.html)>

1.21.0

[src]

impl [From](../../std/convert/trait.From.html "trait std::convert::From")<[String](../../std/string/struct.String.html "struct std:🧵:String")> for [Arc](../../std/sync/struct.Arc.html "struct std::sync::Arc")<[str](../primitive.str.html)>

1.21.0

[src]

`impl From<Box> for Arc where

T: ?Sized, `

1.21.0

[src]

`impl<'a, T> From<&'a [T]> for Arc<T[]> where

T: Clone, `

1.21.0

[src]

impl<T> [From](../../std/convert/trait.From.html "trait std::convert::From")<[Vec](../../std/vec/struct.Vec.html "struct std::vec::Vec")<T>> for [Arc](../../std/sync/struct.Arc.html "struct std::sync::Arc")<[[](../primitive.slice.html)T[]](../primitive.slice.html)>

1.21.0

[src]

`impl Borrow for Arc where

T: ?Sized, `[src]

`impl Ord for Arc where

T: Ord + ?Sized, `[src]

fn [cmp](../../std/cmp/trait.Ord.html#tymethod.cmp)(&self, other: &[Arc](../../std/sync/struct.Arc.html "struct std::sync::Arc")<T>) -> [Ordering](../../std/cmp/enum.Ordering.html "enum std::cmp::Ordering")[src]

Comparison for two Arcs.

The two are compared by calling cmp() on their inner values.

use std::sync::Arc; use std::cmp::Ordering;

let five = Arc::new(5);

assert_eq!(Ordering::Less, five.cmp(&Arc::new(6)));Run

fn [max](../../std/cmp/trait.Ord.html#method.max)(self, other: Self) -> Self

1.21.0

[src]

Compares and returns the maximum of two values. Read more

fn [min](../../std/cmp/trait.Ord.html#method.min)(self, other: Self) -> Self

1.21.0

[src]

Compares and returns the minimum of two values. Read more

`impl Clone for Arc where

T: ?Sized, `[src]

fn [clone](../../std/clone/trait.Clone.html#tymethod.clone)(&self) -> [Arc](../../std/sync/struct.Arc.html "struct std::sync::Arc")<T>[src]

Makes a clone of the Arc pointer.

This creates another pointer to the same inner value, increasing the strong reference count.

use std::sync::Arc;

let five = Arc::new(5);

Arc::clone(&five);Run

fn [clone_from](../../std/clone/trait.Clone.html#method.clone%5Ffrom)(&mut self, source: [&](../primitive.reference.html)Self)[src]

Performs copy-assignment from source. Read more

`impl Hash for Arc where

T: Hash + ?Sized, `[src]

`impl PartialEq<Arc> for Arc where

T: PartialEq + ?Sized, `[src]

fn [eq](../../std/cmp/trait.PartialEq.html#tymethod.eq)(&self, other: &[Arc](../../std/sync/struct.Arc.html "struct std::sync::Arc")<T>) -> [bool](../primitive.bool.html)[src]

Equality for two Arcs.

Two Arcs are equal if their inner values are equal.

use std::sync::Arc;

let five = Arc::new(5);

assert!(five == Arc::new(5));Run

fn [ne](../../std/cmp/trait.PartialEq.html#method.ne)(&self, other: &[Arc](../../std/sync/struct.Arc.html "struct std::sync::Arc")<T>) -> [bool](../primitive.bool.html)[src]

Inequality for two Arcs.

Two Arcs are unequal if their inner values are unequal.

use std::sync::Arc;

let five = Arc::new(5);

assert!(five != Arc::new(6));Run

`impl Display for Arc where

T: Display + ?Sized, `[src]

`impl Eq for Arc where

T: Eq + ?Sized, `[src]

`impl AsRef for Arc where

T: ?Sized, `

1.5.0

[src]

`impl Default for Arc where

T: Default, `[src]

fn [default](../../std/default/trait.Default.html#tymethod.default)() -> [Arc](../../std/sync/struct.Arc.html "struct std::sync::Arc")<T>[src]

Creates a new Arc<T>, with the Default value for T.

use std::sync::Arc;

let x: Arc = Default::default(); assert_eq!(*x, 0);Run

`impl Debug for Arc where

T: Debug + ?Sized, `[src]

`impl Deref for Arc where

T: ?Sized, `[src]

type [Target](../../std/ops/trait.Deref.html#associatedtype.Target) = T

The resulting type after dereferencing.

fn [deref](../../std/ops/trait.Deref.html#tymethod.deref)(&self) -> [&](../primitive.reference.html)T[src]

Dereferences the value.

`impl PartialOrd<Arc> for Arc where

T: PartialOrd + ?Sized, `[src]

fn [partial_cmp](../../std/cmp/trait.PartialOrd.html#tymethod.partial%5Fcmp)(&self, other: &[Arc](../../std/sync/struct.Arc.html "struct std::sync::Arc")<T>) -> [Option](../../std/option/enum.Option.html "enum std::option::Option")<[Ordering](../../std/cmp/enum.Ordering.html "enum std::cmp::Ordering")>[src]

Partial comparison for two Arcs.

The two are compared by calling partial_cmp() on their inner values.

use std::sync::Arc; use std::cmp::Ordering;

let five = Arc::new(5);

assert_eq!(Some(Ordering::Less), five.partial_cmp(&Arc::new(6)));Run

fn [lt](../../std/cmp/trait.PartialOrd.html#method.lt)(&self, other: &[Arc](../../std/sync/struct.Arc.html "struct std::sync::Arc")<T>) -> [bool](../primitive.bool.html)[src]

Less-than comparison for two Arcs.

The two are compared by calling < on their inner values.

use std::sync::Arc;

let five = Arc::new(5);

assert!(five < Arc::new(6));Run

fn [le](../../std/cmp/trait.PartialOrd.html#method.le)(&self, other: &[Arc](../../std/sync/struct.Arc.html "struct std::sync::Arc")<T>) -> [bool](../primitive.bool.html)[src]

'Less than or equal to' comparison for two Arcs.

The two are compared by calling <= on their inner values.

use std::sync::Arc;

let five = Arc::new(5);

assert!(five <= Arc::new(5));Run

fn [gt](../../std/cmp/trait.PartialOrd.html#method.gt)(&self, other: &[Arc](../../std/sync/struct.Arc.html "struct std::sync::Arc")<T>) -> [bool](../primitive.bool.html)[src]

Greater-than comparison for two Arcs.

The two are compared by calling > on their inner values.

use std::sync::Arc;

let five = Arc::new(5);

assert!(five > Arc::new(4));Run

fn [ge](../../std/cmp/trait.PartialOrd.html#method.ge)(&self, other: &[Arc](../../std/sync/struct.Arc.html "struct std::sync::Arc")<T>) -> [bool](../primitive.bool.html)[src]

'Greater than or equal to' comparison for two Arcs.

The two are compared by calling >= on their inner values.

use std::sync::Arc;

let five = Arc::new(5);

assert!(five >= Arc::new(5));Run

`impl Pointer for Arc where

T: ?Sized, `[src]

`impl Drop for Arc where

T: ?Sized, `[src]

fn [drop](../../std/ops/trait.Drop.html#tymethod.drop)(&mut self)[src]

Drops the Arc.

This will decrement the strong reference count. If the strong reference count reaches zero then the only other references (if any) areWeak, so we drop the inner value.

use std::sync::Arc;

struct Foo;

impl Drop for Foo { fn drop(&mut self) { println!("dropped!"); } }

let foo = Arc::new(Foo); let foo2 = Arc::clone(&foo);

drop(foo);
drop(foo2); Run

`impl Send for Arc where

T: Send + Sync + ?Sized, `[src]

impl [From](../../std/convert/trait.From.html "trait std::convert::From")<[CString](../../std/ffi/struct.CString.html "struct std::ffi::CString")> for [Arc](../../std/sync/struct.Arc.html "struct std::sync::Arc")<[CStr](../../std/ffi/struct.CStr.html "struct std::ffi::CStr")>

1.24.0

[src]

impl<'a> [From](../../std/convert/trait.From.html "trait std::convert::From")<&'a [CStr](../../std/ffi/struct.CStr.html "struct std::ffi::CStr")> for [Arc](../../std/sync/struct.Arc.html "struct std::sync::Arc")<[CStr](../../std/ffi/struct.CStr.html "struct std::ffi::CStr")>

1.24.0

[src]

impl [From](../../std/convert/trait.From.html "trait std::convert::From")<[OsString](../../std/ffi/struct.OsString.html "struct std::ffi::OsString")> for [Arc](../../std/sync/struct.Arc.html "struct std::sync::Arc")<[OsStr](../../std/ffi/struct.OsStr.html "struct std::ffi::OsStr")>

1.24.0

[src]

impl<'a> [From](../../std/convert/trait.From.html "trait std::convert::From")<&'a [OsStr](../../std/ffi/struct.OsStr.html "struct std::ffi::OsStr")> for [Arc](../../std/sync/struct.Arc.html "struct std::sync::Arc")<[OsStr](../../std/ffi/struct.OsStr.html "struct std::ffi::OsStr")>

1.24.0

[src]

impl<T: [RefUnwindSafe](../../std/panic/trait.RefUnwindSafe.html "trait std::panic::RefUnwindSafe") + ?[Sized](../../std/marker/trait.Sized.html "trait std:📑:Sized")> [UnwindSafe](../../std/panic/trait.UnwindSafe.html "trait std::panic::UnwindSafe") for [Arc](../../std/sync/struct.Arc.html "struct std::sync::Arc")<T>

1.9.0

[src]

impl [From](../../std/convert/trait.From.html "trait std::convert::From")<[PathBuf](../../std/path/struct.PathBuf.html "struct std::path::PathBuf")> for [Arc](../../std/sync/struct.Arc.html "struct std::sync::Arc")<[Path](../../std/path/struct.Path.html "struct std::path::Path")>

1.24.0

[src]

impl<'a> [From](../../std/convert/trait.From.html "trait std::convert::From")<&'a [Path](../../std/path/struct.Path.html "struct std::path::Path")> for [Arc](../../std/sync/struct.Arc.html "struct std::sync::Arc")<[Path](../../std/path/struct.Path.html "struct std::path::Path")>

1.24.0

[src]