skyfer 7 / 6 / 4 Регистрация: 06.02.2017 Сообщений: 73 |
||||
1 |
||||
20.11.2018, 21:25. Показов 6162. Ответов 14 Метки mutex (Все метки)
Доброго времени суток.
кто подскажет каким образом можно исправить?
__________________
0 |
Programming Эксперт 94731 / 64177 / 26122 Регистрация: 12.04.2006 Сообщений: 116,782 |
20.11.2018, 21:25 |
Ответы с готовыми решениями: Работа с mutex
Решил блокировать доступ к файлу для разных потоков через Mutex, что то не… mutex m_hShared = OpenMutex(MUTEX_ALL_ACCESS, TRUE,… Mutex 14 |
0 / 0 / 0 Регистрация: 06.10.2014 Сообщений: 27 |
|
21.11.2018, 15:34 |
2 |
Пиши на плюсах. Там все получиться
0 |
16930 / 12507 / 3286 Регистрация: 17.09.2011 Сообщений: 20,745 |
|
23.11.2018, 19:42 |
3 |
skyfer, вы мьютекс захватываете один раз перед циклом, а освободить пытаетесь на каждой итерации, отсюда и ошибка. Gartus13, ну спасибо хоть винду переустановить или вообще линупс поставить не предложили.
1 |
skyfer 7 / 6 / 4 Регистрация: 06.02.2017 Сообщений: 73 |
||||
23.11.2018, 23:07 [ТС] |
4 |
|||
Спасибо за совет, теперь не вылетает. Но не все так, как хотелось бы. Программа может записать пару рядков из файла, иили писать может явно не из начала файла B. Каким образом сделать так, чтобы строго запись была по 1 рядку поочередно и с файла, и с консоли?
0 |
16930 / 12507 / 3286 Регистрация: 17.09.2011 Сообщений: 20,745 |
|
23.11.2018, 23:33 |
5 |
skyfer, вам для этого нужно два мьютекса — назовем их Х и У (мьютекс Й пока не нужен).
0 |
7 / 6 / 4 Регистрация: 06.02.2017 Сообщений: 73 |
|
24.11.2018, 00:20 [ТС] |
6 |
а каким образом создать занятый мьютекс? а то в материалах, которые я читал там не сказано именно про занятость мьютекса, и гугл не особо понимает то. Добавлено через 26 минут
0 |
16930 / 12507 / 3286 Регистрация: 17.09.2011 Сообщений: 20,745 |
|
24.11.2018, 00:26 |
7 |
skyfer, у мьютекса есть конструктор, в который можно передать boolean.
0 |
skyfer 7 / 6 / 4 Регистрация: 06.02.2017 Сообщений: 73 |
||||
24.11.2018, 00:46 [ТС] |
8 |
|||
если я вас правильно понял, то код должен иметь приблизительно такой вид. Но проблема из синхронизацией присутствует, я что-то упустил
0 |
16930 / 12507 / 3286 Регистрация: 17.09.2011 Сообщений: 20,745 |
|
24.11.2018, 11:04 |
9 |
skyfer, не создавайте два потока (StreamWriter) для записи в финальный файл.
0 |
skyfer 7 / 6 / 4 Регистрация: 06.02.2017 Сообщений: 73 |
||||
24.11.2018, 12:22 [ТС] |
10 |
|||
Вроде все сделал в соответствии с вашими рекомендациями, но проблема из синхронизацией осталась.
если я правильно понимаю, то предварительно метод PersonalWrite() блокирует mutexObj1, а потом уже метод ProgramWrite() его освобождает.Формально синхронизация присутствует, либо я чего то не понимаю.
0 |
Psilon Master of Orion 6094 / 4950 / 905 Регистрация: 10.07.2011 Сообщений: 14,522 Записей в блоге: 5 |
||||
25.11.2018, 05:57 |
11 |
|||
skyfer, странная задача, мьютексы тут вообще не нужны Я бы написал как-то так (задача отменяется по обычному сочетанию клавиш ctrl+C):
0 |
7 / 6 / 4 Регистрация: 06.02.2017 Сообщений: 73 |
|
25.11.2018, 10:53 [ТС] |
12 |
к сожалению постановка задачи именно с использованием мьютексов
0 |
Master of Orion 6094 / 4950 / 905 Регистрация: 10.07.2011 Сообщений: 14,522 Записей в блоге: 5 |
|
25.11.2018, 11:40 |
13 |
Добавьте в начало `Mutex mutexObj1 = new Mutex(true);`
0 |
Anklav 447 / 305 / 47 Регистрация: 23.01.2013 Сообщений: 661 |
||||
25.11.2018, 13:17 |
14 |
|||
РешениеПроблема в том, что вы берете Mutex одним потоком, а освобождаете другим. Вам вообще нужно 2 мьютекса? Может вам подойдет один мьютекс + переменная?
0 |
7 / 6 / 4 Регистрация: 06.02.2017 Сообщений: 73 |
|
25.11.2018, 15:07 [ТС] |
15 |
Большое спасибо! Решение оказалось немного большим, чем я предполагал изначально, но все замечательно работает.
0 |
IT_Exp Эксперт 87844 / 49110 / 22898 Регистрация: 17.06.2006 Сообщений: 92,604 |
25.11.2018, 15:07 |
Помогаю со студенческими работами здесь Mutex public static Mutex mut = new Mutex();
Допустим есть код void func () { Многопоточность и Mutex
Искать еще темы с ответами Или воспользуйтесь поиском по форуму: 15 |
Я нашел проблему. Сначала несколько вещей о классе filterCtiCallLog. Я разработал его так, чтобы работать как асинхронно, так и синхронно. Для первого я написал код для асинхронного выполнения. Мне нужен способ инициировать события из потока дочерних работников родителям, чтобы сообщить о рабочем состоянии. Для этого я использовал AsyncOperation класс и метод post. Вот часть кода для запуска события CtiCallsRetrieved.
public class FilterCtiCallLog
{
private int RequestCount = 0;
private AsyncOperation createCallsAsync = null;
private SendOrPostCallback ctiCallsRetrievedPost;
public void CreateFilteredCtiCallLogSync()
{
createCallsAsync = AsyncOperationManager.CreateOperation(null);
ctiCallsRetrievedPost = new SendOrPostCallback(CtiCallsRetrievedPost);
CreateFilteredCtiCallLog();
}
private void CreateFilteredCtiCallLog()
{
int count=0;
//do the job
//............
//...........
//Raise the event
createCallsAsync.Post(CtiCallsRetrievedPost, new CtiCallsRetrievedEventArgs(count));
//...........
//...........
}
public event EventHandler<CtiCallsRetrievedEventArgs> CtiCallsRetrieved;
private void CtiCallsRetrievedPost(object state)
{
CtiCallsRetrievedEventArgs args = state as CtiCallsRetrievedEventArgs;
if (CtiCallsRetrieved != null)
CtiCallsRetrieved(this, args);
}
}
Как вы видите, код выполняется синхронно. Проблема здесь в методе AsyncOperation.Post()
. Я предположил, что если он вызывается в основном потоке, он будет действовать как просто запуск события, а не размещение его в родительский поток. Однако это было не так. Я не знаю, как он работает, но я изменил код, чтобы проверить, называется ли CreateFilteredCtiCallLog
синхронизацией или асинхронным. И если это асинхронный вызов, я использовал метод AsyncOperation.Post
, если нет, я просто вызвал EventHandler
, если он не null
. Вот скорректированный код
public class FilterCtiCallLog
{
private int RequestCount = 0;
private AsyncOperation createCallsAsync = null;
private SendOrPostCallback ctiCallsRetrievedPost;
public void CreateFilteredCtiCallLogSync()
{
createCallsAsync = AsyncOperationManager.CreateOperation(null);
ctiCallsRetrievedPost = new SendOrPostCallback(CtiCallsRetrievedPost);
CreateFilteredCtiCallLog(false);
}
private void CreateFilteredCtiCallLog(bool isAsync)
{
int count=0;
//do the job
//............
//...........
//Raise the event
RaiseEvent(CtiCallsRetrievedPost, new CtiCallsRetrievedEventArgs(count),isAsync);
//...........
//...........
}
public event EventHandler<CtiCallsRetrievedEventArgs> CtiCallsRetrieved;
private void RaiseEvent(SendOrPostCallback callback, object state, bool isAsync)
{
if (isAsync)
createCallsAsync.Post(callback, state);
else
callback(state);
}
private void CtiCallsRetrievedPost(object state)
{
CtiCallsRetrievedEventArgs args = state as CtiCallsRetrievedEventArgs;
if (CtiCallsRetrieved != null)
CtiCallsRetrieved(this, args);
}
}
Спасибо всем за ответы!
Исключение: метод синхронизации объектов был вызван из несинхронизированного блока кода.
У меня есть несколько потоков, которые пишут в один и тот же int. Каждый поток увеличивает целочисленное значение. Каков простой способ синхронизировать операцию приращения. Оператор блокировки работает только с объектом, поэтому я не могу его использовать. Я пробовал также следующее:
static int number=0;
static void Main(string[] args)
{
ThreadStart ts = new ThreadStart(strtThread);
new Thread(ts).Start();
new Thread(ts).Start();
new Thread(ts).Start();
new Thread(ts).Start();
new Thread(ts).Start();
new Thread(ts).Start();
Console.ReadLine();
}
public static void strtThread()
{
bool lockTaken = false;
Monitor.Enter(number,ref lockTaken);
try
{
Random rd = new Random();
int ee = rd.Next(1000);
Console.WriteLine(ee);
Thread.Sleep(ee);
number++;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
if (lockTaken)
{
Monitor.Exit(number);
}
}
}
Это дает мне следующую ошибку:
Метод синхронизации объектов был вызван из несинхронизированного блока кода.
Вы можете использовать Метод Interlocked.Increment для автоматического увеличения целого числа без блокировки:
public static void strtThread()
{
Interlocked.Increment(ref number);
}
Если у вас несколько операторов, вы можете создать объект пример, что вы можете Блокировка:
private static int number = 0;
private static readonly object gate = new object();
public static void strtThread()
{
lock (gate)
{
number++;
}
}
Создан 23 ноя.
Зачем тебе возиться с number
? Думаю, в этом проблема. Попробуй это:
static Object locking = new Object();
static void Main(string[] args)
{
ThreadStart ts = new ThreadStart(strtThread);
new Thread(ts).Start();
new Thread(ts).Start();
new Thread(ts).Start();
new Thread(ts).Start();
new Thread(ts).Start();
new Thread(ts).Start();
Console.ReadLine();
}
public static void strtThread()
{
lock(locking) {
try
{
Random rd = new Random();
int ee = rd.Next(1000);
Console.WriteLine(ee);
Thread.Sleep(ee);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
Создан 23 ноя.
Блокировано. обеспечивает атомарное приращение. В Блокированный класс в общем, «предоставляет атомарные операции для переменных, которые совместно используются несколькими потоками».
Создан 23 ноя.
Не тот ответ, который вы ищете? Просмотрите другие вопросы с метками
c#
.net
multithreading
c#-4.0
or задайте свой вопрос.