Powershell - параллельное и многопоточное использование? - PullRequest
1 голос
/ 30 марта 2020

6 часов спустя, и я все ближе. Начал изучать код Visual Studio против ISE, чтобы я мог легко использовать PowerShell 7. Узнал о -Parallel, а затем о том, как нельзя вызывать переменные в блоке сценариев без использования $ using :. (Это заняло целую вечность!) Попробовал -Ajob часть, но это не подходит для этого. Я в основном беру текстовый файл с 20 строками и ищу совпадения в 300 000 строк CSV.

Мне кажется, я добрался до части, которую просто не могу понять. Я думаю, что мне нужно знать, как использовать «потокобезопасные» объекты на основе ошибки.

$textfile = "C:\test_delete\key_words.txt"
$loglocation = "C:\test_delete\datablob.csv"
$outputfile = "C:\test_delete\test5.csv"

New-Item -Path $outputfile

Get-Content $textfile | ForEach-Object -Parallel {
    Select-String  -Raw -Path $using:loglocation -Pattern $_ |
    Out-File -append $using:outputfile
}

Ошибка Out-File: Line | 3 | Out-File -append $ используя: outputfile | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | Процесс не может получить доступ к файлу 'C: \ test_delete \ test5.csv', поскольку он используется другим процессом.

В справке ForEach-Object, пример 11, он говорит о безопасном использовании потока и В этом примере объявляется переменная = синтаксис, безопасный для потока. Это имеет смысл (вроде). За исключением этого случая, я хочу в конечном итоге объявить параметр для $ outfile, который нужно будет вызывать безопасным способом. Я забегаю вперед, но просто не могу понять, как сделать этот поток безопасным, вызывая $ outfile.

Извините за подробности, это мой первый пост, и просто хочу передать, что я потратил некоторое время, пытаясь получить это. Заранее спасибо!

1 Ответ

0 голосов
/ 30 марта 2020

Вот моя предпочтительная альтернатива - не используйте ForEach-Object -Parallel здесь, это не нужно :

Select-String -Path $loglocation -Pattern (Get-Content $textfile) | Out-File $outputfile -Append

Вот и все, вам не нужно беспокоиться о одновременной записи access:)


Если вы все еще настаиваете, ниже приведено несколько примеров того, как обрабатывать этот конкретный c пример.

Тема "thread- безопасное "назначение словаря в файле справки работает, потому что рассматриваемый тип данных (ConcurrentDictionary<string,object>) реализован с учетом безопасности потоков.

Если вы хотите записать в файл потокобезопасным способом, вы ' Вам нужно будет поддерживать блокировку или мьютекс вручную:

$fileLock = [System.Threading.ReaderWriterLockSlim]::new()

Get-Content $textfile | ForEach-Object -Parallel {
    $lock = $using:fileLock
    try{
        $lock.EnterWriteLock()
        Select-String  -Raw -Path $using:loglocation -Pattern $_ |
        Out-File -append $using:outputfile
    }
    finally{
        if($lock.IsWriteLockHeld){
            $lock.ExitWriteLock()
        }
    }
}

В качестве альтернативы, переместите операции записи за пределы параллели l oop:

Get-Content $textfile | ForEach-Object -Parallel {
    Select-String  -Raw -Path $using:loglocation -Pattern $_
} | Out-File -append $using:outputfile
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...