Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Parallel processing net并行任务是否会耗尽池中的所有线程并导致死锁、应用程序挂起、传入请求无法处理?_Parallel Processing_Deadlock - Fatal编程技术网

Parallel processing net并行任务是否会耗尽池中的所有线程并导致死锁、应用程序挂起、传入请求无法处理?

Parallel processing net并行任务是否会耗尽池中的所有线程并导致死锁、应用程序挂起、传入请求无法处理?,parallel-processing,deadlock,Parallel Processing,Deadlock,net并行任务是否会耗尽池中的所有线程,导致死锁、应用程序挂起、传入请求无法处理 我的asp.net应用程序已挂起。所以我抓了个垃圾桶。 我使用DebugDiag进行分析。 具体如下: 87.40% of threads blocked (229 threads) Total Threads: 232 Running Threads: 232 Idle Threads: 0 Max Threads: 400 Min Threads: 4 DebugDiag报告显示: The fol

net并行任务是否会耗尽池中的所有线程,导致死锁、应用程序挂起、传入请求无法处理

我的asp.net应用程序已挂起。所以我抓了个垃圾桶。 我使用DebugDiag进行分析。 具体如下:

87.40% of threads blocked (229 threads)

Total Threads: 232 
Running Threads: 232 
Idle Threads: 0 
Max Threads: 400 
Min Threads: 4 
DebugDiag报告显示:

The following threads in w3wp.DMP are waiting in a WaitOne

( 20 21 22 28 30 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 215 216 217 218 219 220 221 222 223 224 225 226 227 229 230 231 232 233 234 235 236 237 238 239 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 257 258 259 260 )

87.40% of threads blocked (229 threads)
我发现一个线程得到了写锁,在锁定的同时启动了并行操作。但是在并行任务中,系统方法调用Monitor.ObjWait,写入锁线程被阻塞

Thread 177:
[[HelperMethodFrame_1OBJ] (System.Threading.Monitor.ObjWait)] System.Threading.Monitor.ObjWait(Boolean, Int32, System.Object) 
mscorlib_ni!System.Threading.ManualResetEventSlim.Wait(Int32, System.Threading.CancellationToken)+495 
mscorlib_ni!System.Threading.Tasks.Task.InternalRunSynchronously(System.Threading.Tasks.TaskScheduler)+14a 
System.Linq.Parallel.SpoolingTask.SpoolForAll[[System.__Canon, mscorlib],[System.Int32, mscorlib]](System.Linq.Parallel.QueryTaskGroupState, System.Linq.Parallel.PartitionedStream`2, System.Threading.Tasks.TaskScheduler)+ec 
System.Linq.Parallel.MergeExecutor`1[[System.__Canon, mscorlib]].Execute[[System.Int32, mscorlib]](System.Linq.Parallel.PartitionedStream`2, Boolean, System.Linq.ParallelMergeOptions, System.Threading.Tasks.TaskScheduler, Boolean, System.Linq.Parallel.CancellationState, Int32)+27b 
System.Linq.Parallel.PartitionedStreamMerger`1[[System.__Canon, mscorlib]].Receive[[System.Int32, mscorlib]](System.Linq.Parallel.PartitionedStream`2)+86 
System.Linq.Parallel.ForAllOperator`1[[System.__Canon, mscorlib]].WrapPartitionedStream[[System.Int32, mscorlib]](System.Linq.Parallel.PartitionedStream`2, System.Linq.Parallel.IPartitionedStreamRecipient`1, Boolean, System.Linq.Parallel.QuerySettings)+21f 
[[StubHelperFrame]] 
System.Linq.Parallel.UnaryQueryOperator`2+UnaryQueryOperatorResults+ChildResultsRecipient[[System.__Canon, mscorlib],[System.__Canon, mscorlib]].Receive[[System.Int32, mscorlib]](System.Linq.Parallel.PartitionedStream`2)+130 
System_Core_ni!System.Linq.Parallel.UnaryQueryOperator`2+UnaryQueryOperatorResults[[System.__Canon, mscorlib],[System.__Canon, mscorlib]].GivePartitionedStream(System.Linq.Parallel.IPartitionedStreamRecipient`1)+34f 
System_Core_ni!System.Linq.Parallel.QueryOperator`1[[System.__Canon, mscorlib]].GetOpenedEnumerator(System.Nullable`1, Boolean, Boolean, System.Linq.Parallel.QuerySettings)+2d4 
System_Core_ni!System.Linq.Parallel.ForAllOperator`1[[System.__Canon, mscorlib]].RunSynchronously()+319 
Info.UpdateCache(System.Collections.Generic.List`1, System.Collections.Generic.List`1, MySetting)+e2 
Info.GetInfo(System.Collections.Generic.List`1, MySetting)+4f
许多其他线程试图获得读锁,但写锁没有释放,这些线程被阻塞

[[HelperMethodFrame_1OBJ] (System.Threading.WaitHandle.WaitOneNative)] System.Threading.WaitHandle.WaitOneNative(System.Runtime.InteropServices.SafeHandle, UInt32, Boolean, Boolean) 
mscorlib_ni!System.Threading.WaitHandle.InternalWaitOne(System.Runtime.InteropServices.SafeHandle, Int64, Boolean, Boolean)+14 
System_Core_ni!System.Threading.ReaderWriterLockSlim.WaitOnEvent(System.Threading.EventWaitHandle, UInt32 ByRef, Int32)+a8 
System_Core_ni!System.Threading.ReaderWriterLockSlim.TryEnterWriteLockCore(Int32)+612861 
System_Core_ni!System.Threading.ReaderWriterLockSlim.TryEnterWriteLock(Int32)+28 
Info.UpdateCache(System.Collections.Generic.List`1, System.Collections.Generic.List`1, )+5f 
Info.GetInfo(System.Collections.Generic.List`1, MySetting)+4f
我去检查代码。GetInfo由请求触发,第一个请求将从soa服务获取数据并更新本地缓存,然后其他请求仅从本地缓存获取数据

MyStaticInfo StaticInfo = Instance.GetInfo(new List<int>
        {
            1,2,3,4,5.......
        }, new MySetting
        {
            getInfo=true,
            extrainfo = true
        });

public MyStaticInfo GetInfo(List<int> IDList, MySetting setting)    
{
        .....
    MyStaticInfo requestSoaEntity = this.CreateSoaRequest(IDList, setting);
    MyStaticInfo soaData = this.GetSoaData(requestSoaEntity); //no lock in the method.
    if (soaData != null)
    {
        this.UpdateCache(soaData, IDList, setting);
    }
    ......
}


private MyStaticInfo CreateSoaRequest(List<int> IDList, MySetting setting)
{
    this.cacheLock.EnterReadLock();
    MyStaticInfo result;
    try
    {
        IDList.AsParallel<int>().ForAll(delegate(int ID)
        {
            ......
            result=....
         });
    }
    finally
    {
        this.cacheLock.ExitReadLock();
    }
    return result;
}






private void UpdateCache(MyStaticInfo responseSoa, List<int> IDList, MySetting setting)
{
    this.cacheLock.EnterWriteLock();
    try
    {
        IDList.AsParallel<int>().ForAll(delegate(int ID)
        {
          ......
        });
        if (responseSoa != null)
        {
            responseSoa.AsParallel().ForAll( soa=>
            {
                ........
            });
        }
    }
    finally
    {
        this.cacheLock.ExitWriteLock();
    }
}
我去搜索和查找,它是4.5版本,我的代码在.NET4.0下运行。我发现“InternalRunSynchronously”方法调用“SpinThenBlockingWait”,但“SpinThenBlockingWait”方法没有出现在转储的堆栈跟踪上。此方法在运行时是内联的吗

该代码已经运行了一年多。但就在应用程序挂起的前一天。我认为update方法中的代码还可以。我知道,并行for将阻塞for循环,直到所有迭代完成。是否有可能线程池耗尽,那么并行操作需要线程来执行,因此任务的系统调用中的锁会阻止执行

更新1:

我输出池信息并发现该请求已排队

    0:024> !threadpool
    CPU utilization: 81%
    Worker Thread: Total: 232 Running: 232 Idle: 0 MaxLimit: 400 MinLimit: 4
    Work Request in Queue: 480

0:164> !mlocks
Examining SyncBlocks...
Scanning for ReaderWriterLock instances...
Scanning for holders of ReaderWriterLock locks...
Scanning for ReaderWriterLockSlim instances...
Scanning for holders of ReaderWriterLockSlim locks...
Examining CriticalSections...

ClrThread  DbgThread  OsThread    LockType    Lock              LockLevel
------------------------------------------------------------------------------
.....
0x67       116        0x1e8       thinlock    000000014036a2b0  (recursion:0)
0xab       182        0x268       thinlock    00000001c0724188  (recursion:0)
0xa4       177        0x14cc      RWLockSlim  000000013ff0a358  Writer        
0xa4       177        0x14cc      thinlock    0000000140780278  (recursion:0)
.......

0:024> !dlk
Examining SyncBlocks...
Scanning for ReaderWriterLock instances...
Scanning for holders of ReaderWriterLock locks...
Scanning for ReaderWriterLockSlim instances...
Scanning for holders of ReaderWriterLockSlim locks...
Examining CriticalSections...
Scanning for threads waiting on SyncBlocks...
Scanning for threads waiting on ReaderWriterLock locks...
Scanning for threads waiting on ReaderWriterLocksSlim locks...
Scanning for threads waiting on CriticalSections...
No deadlocks detected.

未找到死锁。

为什么仍有230个线程在运行?如果正在运行的任务依赖于无法启动的排队工作,则会导致死锁。可能,您应该限制并行操作的数量。有230个线程正在运行,这是因为请求正在到来。这些线程的调用堆栈类似于上面列出的第二个调用堆栈。它们被ReaderWriterLockSlim.tryEnterWriteLockInt32阻塞。我建议不要有那么多线程,这样就不会出现池耗尽问题。当然,你可以增加限制,但在极少数情况下,任何更高的限制都可能被用尽,这一威胁永远存在。当线程池不能及时启动新工作时,实际上不可能可靠地启动多线程。从转储中,我看到并行程序没有启动许多线程。但这一要求很快就来了。我更新并添加了更多信息。
    0:024> !threadpool
    CPU utilization: 81%
    Worker Thread: Total: 232 Running: 232 Idle: 0 MaxLimit: 400 MinLimit: 4
    Work Request in Queue: 480

0:164> !mlocks
Examining SyncBlocks...
Scanning for ReaderWriterLock instances...
Scanning for holders of ReaderWriterLock locks...
Scanning for ReaderWriterLockSlim instances...
Scanning for holders of ReaderWriterLockSlim locks...
Examining CriticalSections...

ClrThread  DbgThread  OsThread    LockType    Lock              LockLevel
------------------------------------------------------------------------------
.....
0x67       116        0x1e8       thinlock    000000014036a2b0  (recursion:0)
0xab       182        0x268       thinlock    00000001c0724188  (recursion:0)
0xa4       177        0x14cc      RWLockSlim  000000013ff0a358  Writer        
0xa4       177        0x14cc      thinlock    0000000140780278  (recursion:0)
.......

0:024> !dlk
Examining SyncBlocks...
Scanning for ReaderWriterLock instances...
Scanning for holders of ReaderWriterLock locks...
Scanning for ReaderWriterLockSlim instances...
Scanning for holders of ReaderWriterLockSlim locks...
Examining CriticalSections...
Scanning for threads waiting on SyncBlocks...
Scanning for threads waiting on ReaderWriterLock locks...
Scanning for threads waiting on ReaderWriterLocksSlim locks...
Scanning for threads waiting on CriticalSections...
No deadlocks detected.