0

I am writing a program that prints out fibonacci numbers. When I tried to implement threading, the program will crash (normally while printing a number, not calculating the next) with the sole message Killed. I have ran dstat --top-oom and my program never shows up (rust-analyzer sits at 754 and does not move when running the program).
Code:

use rug::Integer;
use std::sync::mpsc;
use std::thread;

struct FibSequ {
    curr: Integer,
    next: Integer
}

impl Default for FibSequ {
    fn default() -> Self {
        Self {curr: Integer::from(0), next: Integer::from(1)}
    }
}

impl Iterator for FibSequ {
    type Item = Integer;

    fn next(&mut self) -> Option<Self::Item> {
        let current = self.curr.clone();

        self.curr = self.next.clone();
        self.next = &current + self.next.clone();
        
        Some(current)
    }
}

fn main() {
    let (tx, rx) = mpsc::channel();

    thread::spawn(move || {
        let mut fib = FibSequ::default();
        loop {
            tx.send(fib.next().unwrap()).unwrap();
        }
    });

    for i in rx {
        println!("{}", i);
    }
}

Bin: Bin [md5: 07e3d09f41e1153694ef4e041c7eeb50]

Last bit of output before it crashed:

...7680751160335033301153281304688311853222415855824651640807481Killed
  • Post the code of your program, otherwise it's just impossible to know what's happening. It's very likely there is a subtle bug in your code. – Alejandro May 23 '23 at 14:43
  • That is what the rustexplorer.com link is, have you tried to click on it? – inyourface3445 May 23 '23 at 14:45
  • Please read: [Questions linking to external web sites instead of showing code](https://meta.stackexchange.com/questions/80978/questions-linking-to-external-web-sites-instead-of-showing-code). Code on external sites CAN change without notice.... – Luuk May 23 '23 at 14:46
  • The reason I didn't originally is because I did not want the body of the question to be mostly code and not be able to submit it. – inyourface3445 May 23 '23 at 14:50
  • Try receiving the data with rx: `rx.recv().unwrap()` – rochard4u May 23 '23 at 15:00
  • When i have tried that, both `for i in rx.recv().unwrap()` and `println!("{}", rx.recv().unwrap())` both just printed a 0 and ended without an error code. – inyourface3445 May 23 '23 at 15:05
  • Try: `loop{ println!("{}", rx.recv().unwrap()); }` to update rx – rochard4u May 23 '23 at 15:15
  • 1
    Related: [What killed my process and why?](https://stackoverflow.com/questions/726690/what-killed-my-process-and-why) – Sven Marnach May 23 '23 at 15:27
  • I've build and run it locally in release mode. And it seems that this program leaks memory. I don't know yet what causes it, but this seems to be the case. – Aleksander Krauze May 23 '23 at 15:44

1 Answers1

2

You are using an unbounded channel, which means it is infinitely buffered. Writing the numbers to the terminal is much slower than computing new numbers, so your channel will buffer an increasing amount of numbers. The easiest way to fix this is using a bounded channel instead. All you need to do is replacing mpsc::channel() with something like mpsc::sync_channel(10), allowing for a queue of ten numbers. The program will still eventually oom, but it takes way longer.

On my Ubuntu box the process gets terminated by earlyoom. Since earlyoom is sending SIGTERM, I see Terminated instead of Killed. The event is logged in the syslog:

128994:2023-05-23T17:36:19.036901+02:00 iona earlyoom[1375]: mem avail:  3156 of 31737 MiB ( 9.95%), swap free:    0 of  979 MiB ( 0.00%)
128995:2023-05-23T17:36:19.053830+02:00 iona earlyoom[1375]: low memory! at or below SIGTERM limits: mem 10.00%, swap 10.00%
128996:2023-05-23T17:36:19.053953+02:00 iona earlyoom[1375]: sending SIGTERM to process 1480267 uid 1000 "playground_8tiu": badness 1002, VmRSS 9899 MiB
128997:2023-05-23T17:36:19.143083+02:00 iona earlyoom[1375]: process exited after 0.1 seconds
Sven Marnach
  • 574,206
  • 118
  • 941
  • 841
  • Why do you say that program will eventually oom? If memory is released as quick as it allocated (sync channel forces that), then why would this be the problem? – Aleksander Krauze May 23 '23 at 15:55
  • @AleksanderKrauze The numbers are growing exponentially, so the memory needed to store a single number grows linearly. The iterator is completely unbounded, so you will eventually get to numbers that are too big to fit into memory. This may take a while, depending on how much memory you have. – Sven Marnach May 23 '23 at 16:02
  • Ah, I forgot about that. :) Thanks. – Aleksander Krauze May 23 '23 at 16:03