使用:C++ (MinGW),Qt4.7.4,Vista (OS),intel core2vPro
我需要以完全相同的方式处理2个巨大的文件.所以我想从2个单独的线程中为2个单独的文件调用处理例程.GUI线程没有什么重要的; 只显示一个标签并运行一个事件循环来检查线程终止条件的发射并相应地退出主应用程序.我预计这会同样地利用两个核心(intel core2),但相反,我从任务管理器看到其中一个核心被高度利用而另一个核心没有(尽管不是每次我都运行代码); 处理2个文件所花费的时间远远超过处理一个文件所花费的时间(我认为它应该相等或稍微多一点,但这几乎等于在非线程中一个接一个地处理2个文件应用).我可以以某种方式强制线程使用我指定的核心吗?
QThread* ptrThread1=new QThread;
QThread* ptrThread2=new QThread;
ProcessTimeConsuming* ptrPTC1=new ProcessTimeConsuming();
ProcessTimeConsuming* ptrPTC2=new ProcessTimeConsuming();
ptrPTC1->moveToThread(ptrThread1);
ptrPTC2->moveToThread(ptrThread2);
//make connections to specify what to do when processing ends, threads terminate etc
//display some label to give an idea that the code is in execution
ptrThread1->start();
ptrThread2->start(); //i want this thread to be executed in the core other than the one used above
ptrQApplication->exec(); //GUI event loop for label display …Run Code Online (Sandbox Code Playgroud) 以下代码不能为我编译.
trait A {
fn fun0(&self);
fn fun2(&self) -> Option<Box<Self>>;
}
struct B0 {
id: usize,
}
impl A for B0 {
fn fun0(&self) { println!("Value: {:?}", self.id); }
fn fun2(&self) -> Option<Box<Self>> { Option::None }
}
struct B1 {
id: isize,
}
impl A for B1 {
fn fun0(&self) { println!("Value: {:?}", self.id); }
fn fun2(&self) -> Option<Box<Self>> { Option::Some(Box::new(B1 { id: self.id, })) }
}
enum C {
None,
Put { object: Box<A>, },
}
fn fun1(values: Vec<C>) …Run Code Online (Sandbox Code Playgroud) 鉴于以下内容:
use std::fmt::Debug;
#[derive(Debug)]
enum A<T: Debug> {
X,
Y(T),
}
#[derive(Debug)]
struct B;
type C = A<B>;
// use A<B> as C; // Does not compile
Run Code Online (Sandbox Code Playgroud)
我可以用它作为:
fn main() {
let val0 = A::X::<B>;
let val1 = A::Y::<B>(B);
println!("{:?}\t{:?}", val0, val1);
}
Run Code Online (Sandbox Code Playgroud)
但随后一个以上的泛型参数(如果A,B等了更长的名字,然后到别名它我尝试以下,但它不会编译:
fn main() {
let val0 = C::X;
let val1 = C::Y(B);
println!("{:?}\t{:?}", val0, val1);
}
Run Code Online (Sandbox Code Playgroud)
有错误:
src/main.rs:656:16: 656:20 error: no associated item named `X` found for type `A<B>` in the current scope …Run Code Online (Sandbox Code Playgroud) 我需要Vec在FFI中传递一些元素.通过实验,我发现了一些有趣的观点.我开始给FFI所有3 ptr,len和capacity这样我就可以重建Vec后销毁它:
let ptr = vec.as_mut_ptr();
let len = vec.len();
let cap = vec.capacity();
mem::forget(vec);
extern_fn(ptr, len, cap);
// ...
pub unsafe extern "C" fn free(ptr: *mut u8, len: usize, cap: usize) {
let _ = Vec::from_raw_parts(ptr, len, cap);
}
Run Code Online (Sandbox Code Playgroud)
我想摆脱capacity它,因为它对我的前端没用; 它只是为了让我可以重建我的矢量来释放记忆.
Vec::shrink_to_fit()这很有吸引力,因为它似乎消除了处理能力的需要.不幸的是,关于它的文档并不能保证它会产生len == capacity,因此我认为在期间from_raw_parts()可能会触发未定义的行为.
into_boxed_slice()似乎有一个保证,它将len == capacity从文档中产生,所以我接下来使用它.如果我错了,请纠正我.问题是它似乎不能保证不重新分配.这是一个简单的程序:
fn main() {
let mut v = Vec::with_capacity(1000);
v.push(100u8); …Run Code Online (Sandbox Code Playgroud) 如果我执行以下操作,则会收到错误消息:
struct A;
struct B;
fn consume_a(_a: A) {}
fn consume_b(_b: B) {}
struct C(A, B);
impl C {
fn foo(self: Self) {
consume_a(self.0);
consume_b(self.1);
}
}
fn main() {
let c = Box::new(C(A, B));
// Consume internals
let _a = c.0;
let _b = c.1;
}
Run Code Online (Sandbox Code Playgroud)
error[E0382]: use of moved value: `c`
--> src/main.rs:21:9
|
20 | let _a = c.0;
| -- value moved here
21 | let _b = c.1;
| ^^ value used here after move …Run Code Online (Sandbox Code Playgroud) 我需要extern "C"Rust中的FFI函数,并希望接受一个固定大小的数组.C代码传递的内容如下:
// C code
extern int(*)[4] call_rust_funct(unsigned char (*)[3]);
....
unsigned char a[] = { 11, 255, 212 };
int(*p)[4] = call_rust_funct(&a);
Run Code Online (Sandbox Code Playgroud)
如何为它编写Rust函数?
// Pseudo code - DOESN'T COMPILE
pub unsafe extern "C" fn call_rust_funct(_p: *mut u8[3]) -> *mut i32[4] {
Box::into_raw(Box::new([99i32; 4]))
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用tokio-core,可以弄清楚如何生成事件循环。但是,我不确定两件事-如何正常退出事件循环以及如何退出在事件循环内运行的流。例如,考虑这段简单的代码,它将两个侦听器派生到事件循环中,并等待另一个线程指示退出条件:
extern crate tokio_core;
extern crate futures;
use tokio_core::reactor::Core;
use futures::sync::mpsc::unbounded;
use tokio_core::net::TcpListener;
use std::net::SocketAddr;
use std::str::FromStr;
use futures::{Stream, Future};
use std::thread;
use std::time::Duration;
use std::sync::mpsc::channel;
fn main() {
let (get_tx, get_rx) = channel();
let j = thread::spawn(move || {
let mut core = Core::new().unwrap();
let (tx, rx) = unbounded();
get_tx.send(tx).unwrap(); // <<<<<<<<<<<<<<< (1)
// Listener-0
{
let l = TcpListener::bind(&SocketAddr::from_str("127.0.0.1:44444").unwrap(),
&core.handle())
.unwrap();
let fe = l.incoming()
.for_each(|(_sock, peer)| {
println!("Accepted from {}", peer);
Ok(())
})
.map_err(|e| println!("----- {:?}", e)); …Run Code Online (Sandbox Code Playgroud) 我想在阅读了网上的一些材料后,我在某种程度上理解了内存排序保证的各个方面。然而,仅从软件和理论的角度来看规则似乎有点神奇。这里解释了为什么两个处理器似乎会重新排序的一个例子,它对我实际可视化该过程有很大帮助。所以我的理解是,预取器可以为一个处理器提前加载读取,而不会为另一个处理器加载读取,然后对于外部观察者来说,第一个处理器看起来比第二个处理器更早读取(并且现在可能有可能)在没有同步的情况下具有陈旧的价值),因此会看到指令重新排序。
之后,我实际上从 CPU 的角度寻找更多关于如何产生这种效果的解释。例如,考虑acquire-release栅栏。通常引用的一个经典示例如下:
thread-0: x.store(true,std::memory_order_release);
thread-1: y.store(true,std::memory_order_release);
thread-2:
while(!x.load(std::memory_order_acquire));
if(y.load(std::memory_order_acquire)) ++z;
thread-3:
while(!y.load(std::memory_order_acquire));
if(x.load(std::memory_order_acquire)) ++z;
Run Code Online (Sandbox Code Playgroud)
由于顺序一致性中不存在全序,因此线程 2 可以看到线程 0 首先执行其操作,然后是线程 1,而线程 3 可以看到线程 1 首先执行其操作,然后是线程 0。这z==0可能是一个可能的结果。
如果有一个解释(比如使用四个 cpu,每个 cpu 运行上面的一个线程)以及硬件中会发生什么让我们看到这种重新排序,那将非常有帮助。它不一定是非常复杂的现实世界详细案例(如果这是理解它的唯一方法,也可以是这样)。只是像上面链接的答案所做的那样的近似值,加上有关缓存(或任何参与因素)的内容,我想它应该为我(可能还有许多其他人?)做这件事。
另一种是:
thread-0:
x.store(true,std::memory_order_relaxed);
y.store(true,std::memory_order_release);
thread-1:
while(!y.load(std::memory_order_acquire)); // <------ (1)
if(x.load(std::memory_order_relaxed)) ++z;
Run Code Online (Sandbox Code Playgroud)
再次遵循规则,我可以理解这永远不会得到z==0(假设所有初始值都是 0)以及为什么更改(1)为relaxed可能会得到我们z==0。但它再次显得有点神奇,直到我能想到它是如何在物理上发生的。
因此,任何使用足够数量的处理器及其缓存等进行解释的帮助(或指针)都将是巨大的。
这两个函数,一个特征和一个免费,似乎是相似的,但调用其中一个(特征函数)是允许的,而调用另一个则不是:
trait A {
fn foo(&self) {
bar(self); // 1. Error: `Self` does not have a constant size known at compile-time
A::bar(self); // 2. This works
}
fn bar(&self) {}
}
fn bar(_a: &A) {}
Run Code Online (Sandbox Code Playgroud)
(上面的游乐场链接)
我本来以为在这两种情况下,我通过一个指针,其大小访问是在编译时已知,所以有什么区别和这种现象如何解释呢?
(Rust 1.19稳定)
我的类型A可以包含任何实现的类型,但是可以trait Trait序列化,尽管实现特征的类型Trait可能不是.在我的情况下,它不能 - 它是一个私人非对称密钥:
extern crate serde;
#[macro_use]
extern crate serde_derive;
use serde::de::DeserializeOwned;
use serde::Serialize;
trait Trait {
type SerialisableType: Clone + Serialize + DeserializeOwned;
fn inner(&self) -> &Self::SerialisableType;
}
#[derive(Serialize, Deserialize)]
enum A<T: Trait> {
Variant0(B<T>), // *** NOTE: Compiles if this is commented ***
Variant1(T::SerialisableType),
}
#[derive(Serialize, Deserialize)]
struct B<T: Trait> {
inner: T::SerialisableType,
}
// ==============================================
struct NonSerialisable {
serialisable: Serialisable,
}
impl Trait for NonSerialisable {
type SerialisableType = Serialisable; …Run Code Online (Sandbox Code Playgroud)