LINUX.ORG.RU
ФорумTalks

Rust, история успеха. TIOBE, июль 2025, почетное 18 место.

 , ,


0

2

итак, за год раст свалится в tiobe c 13го на 18е место, уступив даже какому-то Scratch(17 место), а дедушка Object Pascal, гнет раста одной левой, своим 10м местом.

https://www.tiobe.com/tiobe-index/

Как и положено на первом месте Пытон, на втором С++. :)

короче раст уходит туда, куда и изначально позиционировался - в область маргинальных статистических шумов, и агрессивный маркетинг работает только в краткосрочной перспективе.

Перемещено dataman из development

★★★

Последнее исправление: dataman (всего исправлений: 2)
Ответ на: комментарий от no-such-file

Что предлагает раст? Использовать более сложную теорию.

Нет, таких предложений не наблюдается. Запретить писать код вне unsafe и оставить только возможность дёргать готовое апи - это не теория и уж тем более не сложная.

anonymous
()
Ответ на: комментарий от gaylord

rust

1  use std::sync::{Arc, Mutex, Condvar};
2  use std::thread;
3  
4  fn main() {
5      let data = Arc::new((Mutex::new(0), Condvar::new()));
6      let data_clone = Arc::clone(&data);
7  
8      let writer = thread::spawn(move || {
9          let (lock, cvar) = &*data_clone;
10         let mut value = lock.lock().unwrap();
11         *value = 42;
12         println!("[Writer] Wrote: {}", *value);
13         cvar.notify_one();
14     });
15 
16     let reader = thread::spawn(move || {
17         let (lock, cvar) = &*data;
18         let mut value = lock.lock().unwrap();
19         while *value == 0 {
20             value = cvar.wait(value).unwrap();
21         }
22         println!("[Reader] Read: {}", *value);
23     });
24 
25     writer.join().unwrap();
26     reader.join().unwrap();
27 }

c++

1  #include <iostream>
2  #include <thread>
3  #include <mutex>
4  #include <condition_variable>
5  
6  std::mutex mtx;
7  std::condition_variable cv;
8  int data = 0;
9  bool ready = false;
10 
11 void writer() {
12     std::unique_lock<std::mutex> lock(mtx);
13     data = 42;
14     ready = true;
15     std::cout << "[Writer] Wrote: " << data << std::endl;
16     cv.notify_one();
17 }
18 
19 void reader() {
20     std::unique_lock<std::mutex> lock(mtx);
21     cv.wait(lock, []{ return ready; });
22     std::cout << "[Reader] Read: " << data << std::endl;
23 }
24 
25 int main() {
26     std::thread t1(writer);
27     std::thread t2(reader);
28     t1.join();
29     t2.join();
30     return 0;
31 }

обрати внимание на простоту кода ридера и райтера на с++

alysnix ★★★
() автор топика
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от gaylord

Rust’s rich type system and ownership model guarantee memory-safety

Нет, ничего такого в расте нет. Если на языке невозможно написать даже простейший вектор - это точно не тот язык, в котором есть «rich type system and ownership model».

anonymous
()
Ответ на: комментарий от gaylord

в закрытой стойке

teamviewer

Это что-то виндовозное? А какое отношение имеет винда к закрытым стойкам?

anonymous
()
Ответ на: комментарий от anonymous

Ты пропустил слово «объективную».

Не переживай, не пропустил.

anonymous
()
Ответ на: комментарий от anonymous

раст от этого никак не защищает и не считает уязвимостью - т. е. в этом плане от сишки отличий нет. Их конечно нет и в остальных планах, но это ладно.

Очень жирно, очень. В Rust, память, занимаемая переменной, освобождается автоматически, при покидании области видимости. В C каждый раз надо закатывать солнце вручную. Ещё и не забыть учесть, что если в функции идёт 15 вызовов далее, которые могут завершиться с ошибкой, то после каждого вызова надо освободить все те ресурсы, которые были получены до вызова, и не забыть ни одного. С этим не так много людей справляется без ошибок. Да и сама идея вручную выписывать такие вещи, кажется мне весьма порочной. Всегда будет порождать ошибки, потому что идеально внимательных людей не бывает, и приводить к запутанному загромождённому коду, где надо продираться сквозь ручное управление ресурсами (памятью), чтобы понять общий замысел кода.

А так, конечно, никакой разницы.

Chiffchaff
()
Ответ на: комментарий от seiken

так мне продукт нужен

Ну да, и поэтому на расте никаких продуктов даже спустя 15 лет нет. Поэтому твой рассказ про «ошибки на си находятся и исправляются» не особо релевантен. Даже если бы это было не так, сравнивать всё равно не с чем. Нет кода на расте - нет ошибок в коде на расте.

anonymous
()
Ответ на: комментарий от alysnix

Очень надуманный вариант решения!

RUST

use std::sync::mpsc;
use std::thread;

fn main() {
    let (sender, receiver) = mpsc::channel();

    let writer = thread::spawn(move || {
        let value = 42;
        println!("[Writer] Wrote: {}", value);
        sender.send(value).unwrap();
    });

    let reader = thread::spawn(move || {
        let value = receiver.recv().unwrap();
        println!("[Reader] Read: {}", value);
    });

    writer.join().unwrap();
    reader.join().unwrap();
}

C++ V1

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>

int main() {
    std::queue<int> channel;
    std::mutex mtx;
    std::condition_variable cv;

    auto writer = std::thread([&]() {
        int value = 42;
        std::cout << "[Writer] Wrote: " << value << std::endl;
        {
            std::lock_guard<std::mutex> lock(mtx);
            channel.push(value);
        }
        cv.notify_one();
    });

    auto reader = std::thread([&]() {
        std::unique_lock<std::mutex> lock(mtx);
        cv.wait(lock, [&]() { return !channel.empty(); });
        int value = channel.front();
        channel.pop();
        std::cout << "[Reader] Read: " << value << std::endl;
    });

    writer.join();
    reader.join();
    return 0;
}

C++ v2

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <stop_token>

template<typename T>
class SyncQueue {
    std::queue<T> queue;
    std::mutex mtx;
    std::condition_variable_any cv;
public:
    void push(T value) {
        std::lock_guard lock(mtx);
        queue.push(value);
        cv.notify_one();
    }

    T pop(std::stop_token stop) {
        std::unique_lock lock(mtx);
        cv.wait(lock, stop, [this]() { return !queue.empty(); });
        T value = queue.front();
        queue.pop();
        return value;
    }
};

int main() {
    SyncQueue<int> channel;

    auto writer = std::jthread([&](std::stop_token) {
        int value = 42;
        std::cout << "[Writer] Wrote: " << value << std::endl;
        channel.push(value);
    });

    auto reader = std::jthread([&](std::stop_token st) {
        int value = channel.pop(st);
        std::cout << "[Reader] Read: " << value << std::endl;
    });

    return 0;
}
Silerus ★★★★
()
Ответ на: комментарий от Chiffchaff

Очень жирно, очень.

С «массой утечек в почти каждой либе/приложении на си» решил замять? Достойно.

В Rust, память, занимаемая переменной, освобождается автоматически, при покидании области видимости.

Во первых, в расте нет переменных. Во вторых, в сишке также представляешь. Да и в большинстве друших языков тоже.

В C каждый раз надо закатывать солнце вручную.

В фантазиях.

Ещё и не забыть учесть, что если в функции идёт 15 вызовов далее, которые могут завершиться с ошибкой, то после каждого вызова надо освободить все те ресурсы, которые были получены до вызова, и не забыть ни одного. С этим не так много людей справляется без ошибок.

Они освобождаются сами/автоматически. Посети курсы по сишке.

идея вручную выписывать такие вещи

Нет, такой идеи в сишке нет. В отличии от раста, кстати, где лайфтаймы пишутся именно что вручную кроме пары простейших случаев.

А так, конечно, никакой разницы.

Ну да, о чём сразу и было сказано.

anonymous
()
Ответ на: комментарий от Chiffchaff

В C каждый раз надо закатывать солнце вручную

если вы там раст сравниваете с си, то компилятор раста обьемом в 50 компиляторов си. это вообще несопоставимые языки.

сравнивайте раст с плюсами. в плюсах ничего вручную закатывать не надо, там на raii даже эксепшены навешены.

си очень легкий, системный язычог. в принципе если в си добавить деструкторы к структурам(а это довольно просто), и не иметь наследования - получится тоже raii в легкой форме.

alysnix ★★★
() автор топика
Ответ на: комментарий от alysnix

Вот тебе такое же как на плюсах:

use std::sync::{Mutex, Condvar};
use std::thread;

static MUTEX: Mutex<u32> = Mutex::new(0);
static CV: Condvar = Condvar::new();

fn writer() {
    let mut value = MUTEX.lock().unwrap();
    *value = 42;
    println!("[Writer] Wrote: {}", *value);
    CV.notify_one();
}

fn reader() {
    let mut value = MUTEX.lock().unwrap();
    while *value == 0 {
        value = CV.wait(value).unwrap();
    }
    println!("[Reader] Read: {}", *value);
}

fn main() {
    let writer = thread::spawn(writer);
    let reader = thread::spawn(reader);

    writer.join().unwrap();
    reader.join().unwrap();
}
gaylord
()
Ответ на: комментарий от Chiffchaff

А я считаю, что модель безопасности Rust действительно хороша, но они просто вынули все «кишки» наружу и это заставляет думать как компилятор.

У меня есть идея как сделать гораздо лучше и я её обязательно реализую. Дайте только срок (3-6 лет по предварительным оценкам).

unDEFER ★★★★★
()
Ответ на: комментарий от unDEFER

Ещё проблема в том что авторы сломались на последнем метре и никак не могут принести bitfields, variables integers и pinned places. Ну то есть буквально все то что нужно для системщины куда они так активно хотят.

gaylord
()
Ответ на: комментарий от Silerus

не надо усложнять код, и в случае раста использовать каналы, а в случае плюсов - делать каналы ручками прям в коде.

каналы в плюсах разумеется будут сделаны библиотечными, и все эти очереди спрятаны за классом(или шаблоном) канал с простым интерфейсом.

счас интересен самый кондовый код с записью одного числа. то есть на плюсах нарисован канал емкостью в 1 значение.

alysnix ★★★
() автор топика
Ответ на: комментарий от alysnix

тогда lock_guard убери - это тоже кишки библиотеки ( честненько mtx.lock mtx.unlock), и да почему у тебя в одном случае кортежи, которые и выглядят монструозно, а в другом случае нет

Silerus ★★★★
()
Ответ на: комментарий от Silerus

Мне кажется мы пожем постановить что @alysnix натворил странного и код по большей части один и тот же.

gaylord
()
Ответ на: комментарий от Silerus

Не знаю, к чему выше был написан код, на который ты отвечаешь, но сравнивать нужно языки, а не либы.

#include <print>
#include <thread>

int data, ready;

void writer() {
  data = 42;
  std::println("[Writer {}] Wrote: {}", std::this_thread::get_id(), data);
  __atomic_store_n(&ready, 1, __ATOMIC_RELEASE);
}
void reader() {
  while (!__atomic_load_n(&ready, __ATOMIC_ACQUIRE));
  std::println("[Reader {}] Read: {}", std::this_thread::get_id(), data);
}

int main() {
  std::thread t1{writer}, t2{reader};
  t1.join();
  t2.join();
}

Вот код на цпп без либ.

anonymous
()
Ответ на: комментарий от anonymous

Да, я живу в актуальном мире. На нет и суда нет.

seiken ★★★★★
()
Ответ на: комментарий от gaylord
let mut value = MUTEX.lock().unwrap();

я вот этого не понял. value появляется откуда-то из лока мьютекса…это как вообще понимать?

в плюсовом коде есть флаг ready, говорящий о том, что данные записаны.

в растовом похоже флага нет, и данные просто проверяются не на ноль. это так? если так, то как записать ноль, который тоже данные.

и еще - unwrap может дать облом. это как-то в коде обрабатывается?

alysnix ★★★
() автор топика
Ответ на: комментарий от alysnix

я вот этого не понял. value появляется откуда-то из лока мьютекса…это как вообще понимать?

Доступ к данным идет через MutexGuard<>, который гарантирует, что ты не напишешь:

value = 42;
mutex.lock().unwrap();

вместо

mutex.lock().unwrap();
value = 42;

в плюсовом коде есть флаг ready, говорящий о том, что данные записаны.

Ну так его и сюда можно засунуть.

и еще - unwrap может дать облом. это как-то в коде обрабатывается?

В плюсовом коде могут выскочить эксцепшоны, они у тебя тоже никак не обрабатываются.

gaylord
()
Ответ на: комментарий от gaylord

Не будет, не переживай. А если мне понадобится «уснуть» - я дам команду планировщику и тред «уснёт»(и не будет «жечь»). И это всё опять без либ.

anonymous
()
Ответ на: комментарий от anonymous

это не та задача. не мути воду анонимус. вопрос был про реальные треды, а не код на атомиках.

хочешь на атомиках - открывай тему. я не против. но это не то, и только пустит дискуссию не в ту сторону.

alysnix ★★★
() автор топика
Ответ на: комментарий от anonymous

Не будет, не переживай. А если мне понадобится «уснуть» - я дам команду планировщику и тред «уснёт»(и не будет «жечь»). И это всё опять без либ.

И это ли не прекрасно, только задача-то была другая.

gaylord
()
Ответ на: комментарий от alysnix

лок идет на конкретные данные, а не на область кода, как в с++. т.е в данном случае заблокирована именно переменная. А в с++ у тебя блокируется все что между двумявызовами lock unlock - там может быть заблокированы и другие переменные.

Silerus ★★★★
()
Ответ на: комментарий от alysnix

это не та задача

Это та задача, просто ты не умеешь в код, а просто выучил трюк «мьютекс» и теперь его везде суёшь. Прямо как твои оппоненты - в общем, вы нашли друг друга.

вопрос был про реальные треды, а не код на атомиках

Это и есть реальные треды. Ты там спроси у нейры, как устроен внутри твой мутех - узнаешь много интересного.

но это не то, и только пустит дискуссию не в ту сторону.

Нет у тебя никакой стороны - ты не ориентируешься в теме.

anonymous
()
Ответ на: комментарий от alysnix

Ваще та же срань:

use std::sync::{Mutex, Condvar};
use std::thread;

struct Data {
    value: u32,
    ready: bool,
}

static MUTEX: Mutex<Data> = Mutex::new(Data { 
    value: 0,
    ready: false,
});
static CV: Condvar = Condvar::new();

fn writer() {
    let mut data = MUTEX.lock().unwrap();
    data.value = 42;
    data.ready = true;
    println!("[Writer] Wrote: {}", data.value);
    CV.notify_one();
}

fn reader() {
    let mut data = MUTEX.lock().unwrap();
    while !data.ready {
        data = CV.wait(data).unwrap();
    }
    println!("[Reader] Read: {}", data.value);
}

fn main() {
    let writer = thread::spawn(writer);
    let reader = thread::spawn(reader);

    writer.join().unwrap();
    reader.join().unwrap();
}
gaylord
()
Ответ на: комментарий от gaylord

И это ли не прекрасно, только задача-то была другая.

Что «прекрасно», что я могу на языке без либ написать любую задачу? - да это прекрасно. А вот на расте нельзя написать ни один из вариантов задачи.

Но задачи такой(в твоей «трактовке») не было, не переживай, опять же.

anonymous
()
Ответ на: комментарий от anonymous

царь, ты клоун. не мешай дискуссии. ты даже не видишь что твой сраный код жрет процессор, за что даже в третьем классе отрывают голову.

ридер может стоять в ожидании час, и только потом райтер запишет данные. а твои атомики за это время процессор спалят.

а если ты начнешь вручную управлять слипом, ты в конце концов напишешь cond_var, который для того и сделан. Если хочешь cond_var написать в сто пицотый раз, напиши отдельно и приходи.

alysnix ★★★
() автор топика
Ответ на: комментарий от gaylord

Можешь, но зачем?

Затем, чтобы писать приложения и библиотеки. Пошло в ход классическое «я не могу - значит не нужно»? Слишком слабо.

anonymous
()
Ответ на: комментарий от gaylord

теперь понятно. код аналогичный. но плюсовый, который в лоб, почище выглядит.

вообще никто не мешает в плюсах сделать мутекс, лочащий именно данные и возвращающий поинтер(или ссылку). и получить полностью идентичную картину. это прям пара строк всего. ну и кондвар такой же.

опять вопрос -

let mut data = MUTEX.lock().unwrap();

тут ссылка вернулась или копия данных? надеюсь таки ссылка.

alysnix ★★★
() автор топика
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от alysnix

царь

Ты перепутал. Я смотрю нынешний уровень на лоре настолько низок, что «царь» и «сильный тезис, на который нечего ответить» - уже синонимы. Хотя в какой-то мере это верно, но я здесь особо сильных тезисов и не приводил. Просто ты слишком слаб.

ты клоун

Ну да, ну да. Быстропоплыл.

ты даже не видишь что твой сраный код жрет процессор, за что даже в третьем классе отрывают голову.

Он не жрёт процессор, успокойся. И я уже отвечал выше на это - я могу реализовать любой вариант. Причина, опять же, в твоей слабости.

атомики

Кстати, я не заметил сразу. Но там нет никакого «кода на атомиках», как ты ранее утверждал. Там код именно на мутехе, только максимально упрощённом.

а если ты начнешь вручную управлять слипом, ты в конце концов напишешь cond_var, который для того и сделан.

Нет, никакой cond_var мне для этого не нужен. Спроси там у нейронки вариант без mutex/cv, авось она знает.

anonymous
()
Ответ на: комментарий от alysnix

вообще никто не мешает в плюсах сделать мутекс, лочащий именно данные и возвращающий поинтер(или ссылку)

Суть раста в том что он мешает сделать обратное — по умолчанию нужно очень постараться чтобы влететь в датарейс. Проблема в том что для эргономики этого требуются определенные усилия со стороны stdlib и компилятора (те же pinned places), что движется с трудом.

gaylord
()
Ответ на: комментарий от gaylord

ну и вот. написать нахлобучку на класс мутекс и кондвар, которая будет лочить именно данные, и возвращать ссылку - в плюсах - задача на три-пять минут.

итак, чем же раст победил тут плюсы?

alysnix ★★★
() автор топика
Ответ на: комментарий от anonymous

я могу реализовать любой вариант

А тебя тут никто не обсуждает. тема не про тебя, и не про меня, и не про гейлорда, а про rust.

А когда ты всплываешь из говен, и начинаешь якать - ты просто всем мешаешь.

alysnix ★★★
() автор топика
Ответ на: комментарий от alysnix

итак, чем же раст победил тут плюсы?

Тем что ты НЕ можешь сделать датарейс. А в поюсах можешь.

gaylord
()
Ответ на: комментарий от gaylord

Суть раста в том что он мешает сделать обратное — по умолчанию нужно очень постараться чтобы влететь в датарейс.

все стараются как могут. в обсуждаемом же коде пока что вся защита лишь в том, то ты получил ссылку на данные только при залокнутом мьютексе. ну да. какую-то защиту это дает. но и в плюсах это делается легко и просто.

зачем учить раст, если его защиту на многотреде я могу получить за пять минут и в с++?

alysnix ★★★
() автор топика
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от alysnix

А тебя тут никто не обсуждает.

Именно меня(а точнее, царя) ты и пытаешься обсуждать, съехав с темы про языки и код на них.

Ладно, ты реально нулевой нейровкатун. Опять же, как и твой оппонент. Приятной дискуссии!

anonymous
()
Ответ на: комментарий от anonymous

просто отмоли все грехи и приходи. и тебя примут как родного.

alysnix ★★★
() автор топика
Ответ на: комментарий от alysnix

какую-то защиту это дает.

Полную. Невозможно влететь в датарейс при таком подходе.

но и в плюсах это делается легко и просто.

В плюсах это можно сделать затолкав все в структуру, сделать доступ приватным, насовать аксессоров, и тогда получится похожее. Но выглядеть это будет хуже :)

зачем учить раст, если его защиту на многотреде я могу получить за пять минут и в с++?

Тем что количество подводных камней которое нужно держать в голове будет выше.

gaylord
()
Ответ на: комментарий от alysnix

нет не можешь, язык не помешает скопировать эту ссылку, сохранить, утащить в другой тред, и дёрнуть данные с датарейсом вне лока. Ну т.е. в плюсах нет борроу чекера

zurg
()
Последнее исправление: zurg (всего исправлений: 1)
Ответ на: комментарий от zurg

Если засунуть необходимое в структуру под private, и выставить наружу только получение значений, то все хорошо. Но это ломается на первой же структуре.

gaylord
()
Ответ на: комментарий от alysnix

си очень легкий, системный язычог. в принципе если в си добавить деструкторы к структурам(а это довольно просто), и не иметь наследования - получится тоже raii в легкой форме.

полноценный компилятор С вообще можно встроить в приложение (tiny-C) и будет не то чтобы JIT, но компиляция и исполнение по требованию. По объёмам современных прикладов это даже и незаметно :-)

MKuznetsov ★★★★★
()
Закрыто добавление комментариев для недавно зарегистрированных пользователей (со score < 50)