我现在正在签订一份合同,以提高使用 EF 6 作为 ORM 的现代 SaaS SPA Web 应用程序的后端服务的性能。我建议的第一件事是向当前运行单线程的后端服务引入一些多线程。首席软件工程师表示我们不能这样做,因为 EF 6 不是线程安全的。
我不是实体框架方面的专家。我选择的 ORM 是 DevExpress 的 XPO,并且我已经完成了与下面建议的类似的操作,使用该 ORM 没有出现问题。使用 EF 6 这种模式本质上不安全吗?
int[] ids;
using(var db = new ApplicationDbContext())
{
// query to surface id's of records representing work to be done
ids = GetIdsOfRecordsRepresentingSomeTask(db);
}
Parallel.ForEach(ids, id => {
using(var db = new ApplicationDbContext())
{
var processor = new SomeTaskProcessor(db, id);
processor.ExecuteLongRunningProcessThatReadsDbAndCreatesSomeNewRecords();
db.SaveChanges();
}
});
Run Code Online (Sandbox Code Playgroud)
我对此进行了研究,并且我同意 DbContext 不是线程安全的。我建议的模式确实使用多个线程,但单个 DbContext 仅由单个线程以单线程方式访问。领导告诉我,DbContext 本质上是一个单例,这段代码最终会弄乱数据库。我找不到任何东西来支持这个说法。这件事上的领导正确吗?
谢谢
c# parallel-processing multithreading entity-framework entity-framework-6
我知道在Python中,map相当于pool.map来自multiprocessing模块的并行处理类。filterPython 的并行编程中有等效的吗?
import multiprocessing
import numpy as np
import multiprocessing as mp
import ctypes
class Test():
def __init__(self):
shared_array_base = multiprocessing.Array(ctypes.c_double, 100, lock=False)
self.a = shared_array = np.ctypeslib.as_array(shared_array_base)
def my_fun(self,i):
self.a[i] = 1
if __name__ == "__main__":
num_cores = multiprocessing.cpu_count()
t = Test()
def my_fun_wrapper(i):
t.my_fun(i)
with mp.Pool(num_cores) as p:
p.map(my_fun_wrapper, np.arange(100))
print(t.a)
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,我尝试编写一段代码来修改数组,使用multiprocessing. 在每个进程中执行的函数应该修改作为参数传递给索引处的my_fun()数组的值。关于上面的代码,我想知道复制的是什么。a[:]imy_fun()
1)每个进程都复制代码中的任何内容吗?我认为该物体可能是,但理想情况下什么都不是。
2)有没有办法绕过my_fun()对对象使用包装函数?
python parallel-processing numpy multiprocessing python-multiprocessing
设置这个 Leaf Target 的想法是让每个线程有 4 个叶子;因此,如果一个线程提前结束,它将有大量的机会窃取工作。
但是 getCommonPoolParallelism() 不再返回 #cores.. 它而是返回 #cores - 1。那么为什么这是当前的 LEAF_TARGET?
我有一个包含 480k 个节点和 34M 条边的图。我想在此图上使用 Node2Vec 创建节点嵌入。但是,它甚至无法计算转移概率。我使用的是具有 32 个内核和 120 GB RAM 的 Google Cloud Machine。基础设施不是问题,问题是node2vec pip库中的函数_precompute_probabilities不是并行的。它仅使用单个线程来计算转移概率。有没有办法实现并行,或者它们是 Node2Vec 的任何其他并行版本吗?
MPI-3 标准引入了共享内存,共享该内存的所有进程都可以读取和写入该内存,而无需调用 MPI 库。虽然有使用共享或非共享内存的单方面通信的示例,但我没有找到太多有关如何通过直接访问正确使用共享内存的信息。
我最终做了这样的事情,效果很好,但我想知道 MPI 标准是否保证它总是有效?
// initialization:
MPI_Comm comm_shared;
MPI_Comm_split_type(MPI_COMM_WORLD, MPI_COMM_TYPE_SHARED, i_mpi, MPI_INFO_NULL, &comm_shared);
// allocation
const int N_WIN=10;
const int mem_size = 1000*1000;
double* mem[10];
MPI_Win win[N_WIN];
for (int i=0; i<N_WIN; i++) { // I need several buffers.
MPI_Win_allocate_shared( mem_size, sizeof(double), MPI_INFO_NULL, comm_shared, &mem[i], &win[i] );
MPI_Win_lock_all(0, win);
}
while(1) {
MPI_Barrier(comm_shared);
... // write anywhere on shared memory
MPI_Barrier(comm_shared);
... // read on shared memory written by other processes
}
// deallocation
for (int i=0; i<N_WIN; …Run Code Online (Sandbox Code Playgroud) 我一直在使用 tqdm.contrib.concurrent 中的 process_map :https://tqdm.github.io/docs/contrib.concurrent/
如何设置进度条的描述,该进度条在每次迭代中都会发生变化?
我尝试过:(在这里删除了很多代码以简化它......)
from tqdm.contrib.concurrent import process_map
import tqdm
def myfunc(htmlfile):
tqdm.tqdm.set_description(htmlfile)
### function contents go here
r = process_map(myfunc, mylist, max_workers=16)
Run Code Online (Sandbox Code Playgroud)
但我得到AttributeError: 'str' object has no attribute 'desc'
是因为 process_map fromtqdm.contrib.concurrent不能与 set_description from 混合吗tqdm.tqdm?
我遇到一个问题,hangfire 上的某些作业使用相同的参数排队不止一次,这些作业几乎同时排队。
我尝试将工作人员的数量限制为一名,然后用DisableConcurrentExecution.
我使用 sqlserver 作为存储。有人遇到过这个问题吗?有一些技巧可以避免吗?
PS:我DisableConcurrentExecution之所以使用它,是因为在hangfire文档中说互斥体和信号量不能保证该作业仅被调用一次。
PS2:检查我的hangfire 服务器,我注意到我有两个实例,每个实例有 1 个工作人员,所以我认为这是一个并行问题而不是并发问题。
我编写了以下测试应用程序:
main = print $ sum $ map (read . show) [1 .. 10^7]
Run Code Online (Sandbox Code Playgroud)
当我使用和不使用 -N 标志运行它时,我得到以下结果:
$ ghc -O2 -threaded -rtsopts -o test test.hs
...
$ time ./test +RTS -s
50000005000000
real 0m12.411s
user 0m12.367s
sys 0m0.040s
$ time ./test +RTS -s -N12
50000005000000
real 0m22.702s
user 1m14.904s
sys 0m12.608s
Run Code Online (Sandbox Code Playgroud)
似乎 GHC 决定通过将计算分布在不同的核心上来尊重 -N12 标志(结果非常糟糕),但我找不到任何有关当代码不包含显式指令时它如何决定这样做的文档。我缺少一些文档吗?
我有 GHC 版本 8.6.5。
垃圾收集统计:
main = print $ sum $ map (read . show) [1 .. 10^7]
Run Code Online (Sandbox Code Playgroud)
我需要更新一个 100M 元素的数组,并且希望并行执行。 std::for_each(std::execution::par, ...)看起来很棒,除了更新需要根据我正在更新的索引访问其他数组的元素。我尝试并行化的最小串行工作示例可能如下所示:
for (size_t i = 0; i < 100'000'000; i++)
d[i] = combine(d[i], s[2*i], s[2*i+1]);
Run Code Online (Sandbox Code Playgroud)
我当然可以手动生成线程,但这比代码多得多std::for_each,因此找到一种使用标准库来执行此操作的优雅方法会很棒。到目前为止,我发现了一些不太优雅的使用方式for_each,例如:
通过对数组元素的地址使用指针算术来计算索引。
本着 boost 的精神实现我自己的伪造迭代器counting_range。
有一个更好的方法吗?