Hone logo
Hone
Problems

Implementing Atomic Integers in Rust

Modern concurrent programming relies heavily on the ability to perform operations on shared data without race conditions. Rust provides atomic types in its standard library to facilitate this. Your challenge is to understand and utilize these atomic types to safely manage shared integer counters in a multithreaded environment.

Problem Description

The goal of this challenge is to implement a concurrent counter using Rust's atomic integer types. You will simulate multiple threads incrementing a shared counter and then verify that the final value of the counter is correct. This exercise will help you grasp the importance of atomicity in preventing data corruption when multiple threads access the same memory location.

Key Requirements:

  1. Use std::sync::atomic::AtomicUsize: This type represents an unsigned integer that can be safely manipulated by multiple threads.
  2. Create a shared counter: Initialize an AtomicUsize variable that will be shared among threads.
  3. Spawn multiple threads: Create a specified number of threads.
  4. Increment the counter concurrently: Each thread should increment the shared counter a fixed number of times.
  5. Join all threads: Ensure all threads have completed their execution before proceeding.
  6. Read and verify the final count: After all threads have finished, read the final value of the atomic counter and assert that it equals the total number of increments performed across all threads.

Expected Behavior:

When executed, the program should successfully spawn threads, have each thread increment the counter, and then report the final count. The final count must precisely match the expected total increments (number of threads * increments per thread).

Edge Cases:

  • Zero threads: The counter should remain at its initial value (0).
  • One thread: The counter should reflect the increments from that single thread.

Examples

Example 1:

Input:
Number of threads: 4
Increments per thread: 1000

Output:
Final counter value: 4000

Explanation: Four threads are spawned. Each thread increments the AtomicUsize 1000 times. The total expected increments are 4 * 1000 = 4000. The program successfully increments the atomic counter and reports the final value as 4000.

Example 2:

Input:
Number of threads: 1
Increments per thread: 5000

Output:
Final counter value: 5000

Explanation: A single thread is spawned, incrementing the counter 5000 times. The final value is correctly reported as 5000.

Example 3: (Edge Case)

Input:
Number of threads: 0
Increments per thread: 1000

Output:
Final counter value: 0

Explanation: No threads are spawned, so no increments occur. The atomic counter remains at its initial value of 0.

Constraints

  • The number of threads can range from 0 to 1000.
  • The number of increments per thread can range from 0 to 1,000,000.
  • The total number of increments will not exceed the maximum value of usize.
  • The solution must be written in Rust.

Notes

  • Refer to the std::sync::atomic module documentation for details on AtomicUsize and its methods like fetch_add.
  • Consider how to share the AtomicUsize across threads safely. The Arc (Atomically Reference Counted) smart pointer is a good candidate for this.
  • Ensure proper thread synchronization by joining all spawned threads before reading the final counter value.
Loading editor...
rust