我的应用程序使用一种模式,我使用Context#startService()启动服务,并使用Context#bindService()绑定它.这样我就可以独立于任何客户端当前是否绑定它来控制服务的生命周期.但是,我最近注意到,每当我的应用程序被系统杀死时,它很快就会重新启动所有正在运行的服务.此时,服务永远不会被告知停止,这会导致电池耗尽.这是一个最小的例子:
我在这里找到了一个有类似问题的人,但它从未被诊断或解决过.
服务:
@Override
public void onCreate() {
Toast.makeText(this, "onCreate", Toast.LENGTH_LONG).show();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_NOT_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return new Binder();
}
Run Code Online (Sandbox Code Playgroud)
活动:
@Override
protected void onStart() {
super.onStart();
Intent service = new Intent(this, BoundService.class);
startService(service);
bindService(service, mServiceConnection, 0);
}
@Override
protected void onStop() {
unbindService(mServiceConnection);
Toast.makeText(this, "unbindService", Toast.LENGTH_SHORT).show();
super.onStop();
}
Run Code Online (Sandbox Code Playgroud)
为了测试它,我启动了应用程序,它启动了服务并绑定到它.然后我退出了应用程序,解除绑定(但让服务运行).然后我做了
$ adb shell am kill com.tavianator.servicerestart
Run Code Online (Sandbox Code Playgroud)
果然,5秒钟后,"onCreate"吐司出现,表明该服务再次启动.Logcat显示了这个:
$ adb …Run Code Online (Sandbox Code Playgroud) 以下片段:
#include <memory>
#include <utility>
namespace foo
{
template <typename T>
void swap(T& a, T& b)
{
T tmp = std::move(a);
a = std::move(b);
b = std::move(tmp);
}
struct bar { };
}
void baz()
{
std::unique_ptr<foo::bar> ptr;
ptr.reset();
}
Run Code Online (Sandbox Code Playgroud)
不为我编译:
$ g++ -std=c++11 -c foo.cpp
In file included from /usr/include/c++/5.3.0/memory:81:0,
from foo.cpp:1:
/usr/include/c++/5.3.0/bits/unique_ptr.h: In instantiation of ‘void std::unique_ptr<_Tp, _Dp>::reset(std::unique_ptr<_Tp, _Dp>::pointer) [with _Tp = foo::bar; _Dp = std::default_delete<foo::bar>; std::unique_ptr<_Tp, _Dp>::pointer = foo::bar*]’:
foo.cpp:20:15: required from here
/usr/include/c++/5.3.0/bits/unique_ptr.h:342:6: error: call of …Run Code Online (Sandbox Code Playgroud) 例如:
template <typename T>
struct foo
{
using bar = int;
};
// _Z3bazi
void baz(foo<int>::bar quux) {
}
template <typename T>
void baz(typename foo<T>::bar quux) {
}
// _Z3bazIiEvN3fooIT_E3barE
template void baz<int>(foo<int>::bar quux);
Run Code Online (Sandbox Code Playgroud)
为什么要baz<int>提到破败的形式foo呢?怎么没有_Z3bazIiEvi?
这显然是C++ 17 std::default_order<T>提案在水中死亡的原因.
我想加倍一个Stream(没有DoubleStream).意思是我从流开始并想要获得一个新流,其中旧流的每个元素都流式传输两次.所以1,2,3,4,4,5给了我们1,1,2,2,3,3,4,4,4,4,5,5.有没有这样的流操作?
当我尝试使用构建静态库时-flto,我得到未定义的引用错误:
library.cpp:
#include <iostream>
void foo() {
std::cout << "Test!" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
main.cpp:
void foo();
int main() {
foo();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译输出:
$ g++ -flto -c library.cpp
$ ar rcs library.a library.o
$ g++ -flto main.cpp library.a
/tmp/ccZIgxCY.ltrans0.ltrans.o: In function `main':
ccZIgxCY.ltrans0.o:(.text+0x5): undefined reference to `foo()'
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
如果我链接library.o而不是,它工作正常library.a.我错过了什么?这与GCC 4.9.1和binutils 2.24有关.
我更换使用std::map与热路径CPP-B树的btree_map.但是在启用优化的情况下,GCC和Clang抱怨严格的别名违规.问题归结为:
template <typename Key, typename Value>
class btree_map {
public:
// In order to match the standard library's container interfaces
using value_type = std::pair<const Key, Value>;
private:
using mutable_value_type = std::pair<Key, Value>;
struct node_type {
mutable_value_type values[N];
// ...
};
public:
class iterator {
// ...
value_type& operator*() {
// Here we cast from const std::pair<Key, Value>&
// to const std::pair<const Key, Value>&
return reinterpret_cast<value_type&>(node->values[i]);
}
};
std::pair<iterator, bool> insert(const value_type& value) {
// …Run Code Online (Sandbox Code Playgroud) 一些Guava内部类型,例如AbstractMultiset,有这样的模式:
private transient Set<E> elementSet;
@Override
public Set<E> elementSet() {
Set<E> result = elementSet;
if (result == null) {
elementSet = result = createElementSet();
}
return result;
}
Set<E> createElementSet() {
return new ElementSet();
}
Run Code Online (Sandbox Code Playgroud)
我们的想法是延迟创建集合视图(elementSet(),entrySet()),直到实际需要它们为止.进程周围没有锁定,因为如果两个线程同时调用elementSet(),则可以返回两个不同的值.编写该elementSet字段会有竞争,但由于写入引用字段在Java中始终是原子的,因此谁赢得竞争并不重要.
但是,我担心Java内存模型在这里内联的内容.如果createElementSet()和ElementSet的构造函数都被内联,似乎我们可以得到这样的东西:
@Override
public Set<E> elementSet() {
Set<E> result = elementSet;
if (result == null) {
elementSet = result = (allocate an ElementSet);
(run ElementSet's constructor);
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
这将允许另一个线程观察到一个非null但未完全初始化的值 …
一个线程死锁饥饿如果池中的所有线程都在等待同一个池中排队的任务完成发生在一个正常的线程池. ForkJoinPool通过从join()调用内部窃取其他线程的工作来避免这个问题,而不是简单地等待.例如:
private static class ForkableTask extends RecursiveTask<Integer> {
private final CyclicBarrier barrier;
ForkableTask(CyclicBarrier barrier) {
this.barrier = barrier;
}
@Override
protected Integer compute() {
try {
barrier.await();
return 1;
} catch (InterruptedException | BrokenBarrierException e) {
throw new RuntimeException(e);
}
}
}
@Test
public void testForkJoinPool() throws Exception {
final int parallelism = 4;
final ForkJoinPool pool = new ForkJoinPool(parallelism);
final CyclicBarrier barrier = new CyclicBarrier(parallelism);
final List<ForkableTask> forkableTasks = new ArrayList<>(parallelism);
for (int …Run Code Online (Sandbox Code Playgroud) java concurrency multithreading java.util.concurrent fork-join
这个程序:
#include <iostream>
struct Foo {
Foo() {
std::cout << "Foo()\n";
}
~Foo() {
std::cout << "~Foo()\n";
}
};
struct Bar {
Bar() {
std::cout << "Bar()\n";
}
~Bar() {
std::cout << "~Bar()\n";
thread_local Foo foo;
}
};
Bar bar;
int main() {
return 0;
}
Run Code Online (Sandbox Code Playgroud)
打印
Bar()
~Bar()
Foo()
Run Code Online (Sandbox Code Playgroud)
对我来说(GCC 6.1,Linux,x86-64).永远不会调用~Foo().这是预期的行为吗?
c++ multithreading language-lawyer thread-local-storage c++11
以下代码使用GCC 4.9.2编译,但不与Clang 3.5.0编译:
#include <string>
class Foo
{
public:
explicit operator std::string() const;
};
std::string bar{Foo{}}; // Works in g++, fails in clang++
std::string baz(Foo{}); // Works in both
Run Code Online (Sandbox Code Playgroud)
clang ++说:
foo.cpp:9:13: error: no matching constructor for initialization of 'std::string'
(aka 'basic_string<char>')
std::string bar{Foo{}};
^ ~~~~~~~
...: note: candidate constructor not viable: no known conversion from 'Foo' to
'const std::basic_string<char> &' for 1st argument
basic_string(const basic_string& __str);
^
Run Code Online (Sandbox Code Playgroud)
奇怪的是,如果std::string被替换为原始类型,它就可以工作int.
c++ ×6
c++11 ×4
gcc ×3
java ×3
android ×1
b-tree ×1
clang ×1
compiler-bug ×1
concurrency ×1
fork-join ×1
guava ×1
itanium-abi ×1
java-8 ×1
java-stream ×1
lazy-loading ×1
libstdc++ ×1
lto ×1
move ×1
templates ×1