我有这个非常简单的代码,很少抛出"System.ApplicationException:从非同步的代码块调用对象同步方法." 当调用ReleaseMutex()时.
我在逻辑上分析了方法的流程,并且无法理解这种情况如何/为何会发生.根据我的理解,在这种情况下保证互斥锁的所有权:
readonly string mutexKey;
public Logger(string dbServer, string dbName)
{
this.mutexKey = ServiceManagerHelper.GetServiceName(dbServer, dbName);
}
private void Log(LogType type, string message, Exception ex)
{
using (var mutex = new Mutex(false, mutexKey))
{
bool acquiredMutex;
try
{
acquiredMutex = mutex.WaitOne(TimeSpan.FromSeconds(5));
}
catch (AbandonedMutexException)
{
acquiredMutex = true;
}
if (acquiredMutex)
{
try
{
// some application code here
}
finally
{
mutex.ReleaseMutex();
}
}
}
}
Run Code Online (Sandbox Code Playgroud) 如果你看一下描述条件变量(cv)用法的文档,你会看到例如在PThreads和C++中你不需要持有cv的互斥锁来调用这个cv上的notify.而在Java和Python中,您必须锁定互斥锁以执行相同的操作.
有没有一些深层原因为什么事情以这种方式实现(我是关于后一种情况),因为像Java这样的语言的实现最终会使用一些原生的线程工具?
multithreading mutex conditional-statements thread-synchronization
我遇到多个线程必须更新存储在共享向量中的对象的情况。但是,向量非常大,并且要更新的元素数量相对较少。
在最小示例中,可以通过包含要更新的元素的索引的(哈希)集来标识要更新的元素集。因此,代码如下所示:
let mut big_vector_of_elements = generate_data_vector();
while has_things_to_do() {
let indices_to_update = compute_indices();
indices_to_update.par_iter() // Rayon parallel iteration
.map(|index| big_vector_of_elements[index].mutate())
.collect()?;
}
Run Code Online (Sandbox Code Playgroud)
Rust显然不允许这样做:big_vector_of_elements不能同时在多个线程中可变地借用。但是,将每个元素包装在例如Mutex锁中似乎是不必要的:如果没有明确的同步,这种特定情况将是安全的。由于索引来自一组,因此可以保证它们是不同的。par_iter在向量的相同元素上没有两次迭代。
编写一个并行修改向量中元素的程序的最佳方法是什么,在这种情况下,同步已经通过选择索引来解决,但是编译器不理解后者呢?
接近最佳的解决方案是将所有元素包装big_vector_of_elements在某种假设的UncontendedMutex锁中,这是其变体,Mutex在无竞争的情况下非常快,并且在发生争用(甚至发生恐慌)时可能会花费任意长时间。理想情况下,an UncontendedMutex<T>的大小和对齐方式也应与Tany相同T。
可以使用“使用人造丝的并行迭代器”,“使用chunks_mut”或“使用split_at_mut” 来回答多个问题:
这些答案在这里似乎无关紧要,因为这些解决方案意味着迭代整个big_vector_of_elements,然后针对每个元素弄清楚是否需要更改任何内容。从本质上讲,这意味着这样的解决方案如下所示:
let mut big_vector_of_elements = generate_data_vector();
while has_things_to_do() {
let indices_to_update = compute_indices();
for (index, mut element) in big_vector_of_elements.par_iter().enumerate() …Run Code Online (Sandbox Code Playgroud) 我想执行以下算法 - 这必须在Java中完成
for(int i = 0; i< 100; i++){
create 8 threads which perform a task
wait for all threads to finish
}
Run Code Online (Sandbox Code Playgroud)
由于开销(以及每个线程将具有<20毫秒的工作时间的事实),期望线程不被连续地创建和销毁,这带来了线程池1的想法.我也知道使用Executable 2,可以调用shutdown,然后是awaitTermination.然而,在这种情况下由于环路是不可取的.那么如何进行线程同步呢?
我想在线程池中同步线程,就像使用传统线程的join()方法一样.
我有一个多线程程序,主线程是第三方(无法更改)和纯C.我的任务是围绕它构建新模块(在C++中),那些部分驻留在其他线程中,需要使用C程序的界面.基本上只是读取在C线程中存储和更新的一些变量(整数,浮点数,没有复杂).
现在我的问题是:我如何确保在访问这些变量时不会从C接口中获取垃圾,因为在读取时我无法使用互斥锁将其锁定.这甚至可能吗?或者正在编写一个float/int原子操作?
假设一个 Java 线程执行一些 I/O 操作,比如使用传统的阻塞 Java I/O 读取文件。
问题是:等待时线程的状态是什么?
我不知道它是 RUNNING(进行一些主动等待)还是 WAITING(也许有某种监视器在文件数据准备好时唤醒线程)。
我怎样才能找到它?
谢谢。
我有一个简单的问题,我相信,据我所知,一个多线程程序,它们在所有线程之间共享进程的内存空间,包括堆栈,全局内存区域,文件描述符等,我想知道为什么在第一个例子中,存在一致性问题,因为理论上所有线程共享堆栈,在第二个例子中,出现竞争问题。
#include <stdio.h>
#include <pthread.h>
void *thr(void *arg)
{
for(int i = 0; i < 50; i++)
printf("Thread = %zu Value= %d\n", pthread_self(), i);
return NULL;
}
int main(void)
{
pthread_t threads[2];
for(int i = 0; i < 2; i++)
pthread_create(&threads[i], NULL, thr, NULL);
for(int i = 0; i < 2; i++)
pthread_join(threads[i], NULL);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
第二个程序运行有问题
#include <stdio.h>
#include <pthread.h>
int i = 0;
void *thr(void *arg)
{
for(; i < 50; i++)
printf("Thread = %zu Value= %d\n", …Run Code Online (Sandbox Code Playgroud) public void method(Type1 inst1, Type2 inst2) {
synchronized(inst1) {
synchronized(inst2) {
//do something now
}
}
}
Run Code Online (Sandbox Code Playgroud)
从这段代码中我可以理解,一旦一个线程进入该方法,它会在inst1上获取锁,然后在inst2上获取锁,不会释放inst1锁。我假设这两个对象都没有被其他线程锁定。
所以我有一个经典案例"我的代码可行,但我不知道为什么".
我有一个创建线程的程序,当我从扫描仪接收到某个输入时,我将字符串的控制权传递给工作线程.为此,我创建了我的线程wait(),当我从UI线程获得正确的输入时,我通知().
这是我的代码.为简单起见,我刚刚使用了一个线程.
package main;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
class ThreadDemo extends Thread {
private Thread t;
private String threadName;
volatile Boolean keepRunning = true;
private Queue<String> q = new LinkedList<String>();
ThreadDemo( String name){
threadName = name;
System.out.println("Creating " + threadName );
}
public void in(String ex){
q.add(ex);
System.out.println("Added " + ex + "to queue of " + threadName);
synchronized(t){
t.notify();
}
}
public void run() {
System.out.println("Starting to loop.");
while (keepRunning) {
try {
//Why does it …Run Code Online (Sandbox Code Playgroud) 我们有一个用 C# 目标框架 2.0 编写的旧库。最近我们将在现代 .net core 项目中使用它并打算使用async/await. 然而,旧图书馆有很多lock街区。
我们计划添加新async方法来实现相同的逻辑。
例如,
旧代码
void GetOrder()
{
// ...
lock(_lock)
{
//...
}
}
Run Code Online (Sandbox Code Playgroud)
预期结果
async Task AsyncGetOrder()
{
// ...
await DoSomethingWithLock()
}
Run Code Online (Sandbox Code Playgroud)
请给我一些关于如何翻译lock成 的建议async/await。
java ×4
c ×2
mutex ×2
async-await ×1
c# ×1
c++ ×1
concurrency ×1
java-threads ×1
posix ×1
pthreads ×1
rayon ×1
rust ×1
threadpool ×1
vector ×1
wait ×1