典型的malloc(对于x86-64平台和Linux操作系统)是否在开始时天真地锁定互斥锁并在完成时释放它,或者是否以更精巧的方式更智能地锁定互斥锁,从而减少锁争用?如果它确实是第二种方式,它是如何做到的?
在典型的真实世界的程序中,内存分配/释放有多大的瓶颈?任何类型的程序通常都很重要的答案是受欢迎的.malloc/free/garbage收集的正确实现是否足够快,以至于它只是少数极端情况下的瓶颈,或者大多数性能关键型软件都会从尝试保持内存分配量下降或拥有更快的malloc/free /中获益匪浅垃圾收集实施?
注意:我不是在谈论实时的东西.对性能至关重要,我的意思是吞吐量很重要,但延迟并不一定.
编辑:虽然我提到了malloc,但这个问题不是针对C/C++的.
malloc optimization performance garbage-collection memory-management
我是C++新线程的新手,我试图清楚地了解线程之间如何共享/不共享内存.我正在使用std::threadC++ 11.从我在其他SO问题上看到的,堆栈内存只由一个线程拥有,堆内存在线程之间共享.所以从我认为我对堆栈与堆的理解,以下内容应该是正确的:
#include <thread>
using namespace std;
class Obj {
public:
int x;
Obj(){x = 0;}
};
int main() {
Obj stackObj;
Obj *heapObj = new Obj();
thread t([&]{
stackObj.x++;
heapObj->x++;
});
t.join();
assert(heapObj->x == 1);
assert(stackObj.x == 0);
}
Run Code Online (Sandbox Code Playgroud)
请原谅我,如果我搞砸了一堆东西,lambda语法对我来说是非常新的.但希望我正在努力做的是连贯的.这会像我期望的那样表现吗?如果没有,我有什么误解?
正如标题所说,两个或多个线程如何共享它们分配的堆上的内存?我一直在考虑它,我无法弄清楚他们是如何做到的.这是我对这个过程的理解,大概我错了.
任何线程都可以通过进行系统调用来添加或删除堆上给定数量的字节,系统调用返回指向此数据的指针,可能是通过写入线程然后可以复制到堆栈的寄存器.因此,两个线程A和B可以根据需要分配尽可能多的内存.但我没有看到线程A如何知道线程B分配的内存位于何处.我也不知道任何一个线程如何知道其他线程堆栈的位置.多线程程序共享堆,我相信,它可以访问彼此的堆栈,但我无法弄清楚如何.
我尝试搜索这个问题,但只发现了特定于语言的版本,这些版本抽象了细节.
编辑:我试图不是语言或操作系统特定,但我正在使用Linux,我从低级别的角度看待它,我想是汇编.
在我的应用程序中,我有一些本机代码的包装器,它通过JNI桥调用.此本机代码需要在单独的线程中执行(并行处理).但问题是代码有时会"挂起",因此线程需要"强制"终止.不幸的是我没有找到任何"微妙"的方法:一般建议是告诉线程中的代码优雅地退出,但我不能用这个本机代码(这是上面的第三方代码).
我使用Java Concurrent API进行任务提交:
Future<Integer> processFuture = taskExecutor.submit(callable);
try {
result = processFuture.get(this.executionTimeout, TimeUnit.SECONDS).intValue();
}
catch (TimeoutException e) {
// How to kill the thread here?
throw new ExecutionTimeoutException("Execution timed out (max " + this.executionTimeout / 60 + "min)");
}
catch (...) {
... exception handling for other cases
}
Run Code Online (Sandbox Code Playgroud)
Future#cancel()只会中断线程,但不会终止它.所以我使用了以下技巧:
class DestroyableCallable implements Callable<Integer> {
private Thread workerThread;
@Override
public Integer call() {
workerThread = Thread.currentThread();
return Integer.valueOf(JniBridge.process(...));
}
public void stopWorkerThread() {
if (workerThread != null) { …Run Code Online (Sandbox Code Playgroud) 我使用上面的代码使用2个线程递增一个计数器,它独立地使用mut锁和递增计数器.线程进入此函数后,我面临死锁.
pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
void *increment_counter(void *counter_addr)
{
int max = MAX_COUNTER_VALUE;
int iter;
int counter;
for(iter=0;iter< max ;iter++)
// LOCK
pthread_mutex_lock(&mut);
counter++;
// UNLOCK
pthread_mutex_unlock(&mut);
return NULL;
}
Run Code Online (Sandbox Code Playgroud)
谁能告诉我我哪里错了?
如果我生成各种线程,并告诉他们所有使用相同的方法:
internal class Program {
private static DoSomething() {
int result = 0;
Thread.Sleep(1000);
result++;
int ID = Thread.CurrentThread.ManagedThreadId;
Console.WriteLine("Thread {0} return {1}", ID, result);
}
private static Main() {
Thread[] threads = new Thread[50];
for (int i = 0; i < 50; i++)
threads[i] = new Thread(DoSomething);
foreach (Thread t in threads)
t.Start();
}
}
Run Code Online (Sandbox Code Playgroud)
所有线程都会共享相同的堆栈吗?当我运行程序时,所有线程都返回1,所以我猜答案是否定的,但这是否意味着CLR在内存中制作了不同的方法副本?
参考这个结构,发布一个完整的例子会有点太大:
__thread char* buf;
buf = malloc(1000);
Run Code Online (Sandbox Code Playgroud)
Valgrind说这些字节"肯定"丢失了.他们不应该"仍然可以"到达吗?