-
Notifications
You must be signed in to change notification settings - Fork 0
Thread pool #51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Thread pool #51
Changes from all commits
e3c5665
8ff8947
c475034
7d67e90
20a440c
cc1c9db
4386c9d
cc28d0c
c618623
17a8d17
a3f6468
430fe48
23ce907
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
|
|
||
| <PropertyGroup> | ||
| <TargetFramework>net7.0</TargetFramework> | ||
| <ImplicitUsings>enable</ImplicitUsings> | ||
| <Nullable>enable</Nullable> | ||
|
|
||
| <IsPackable>false</IsPackable> | ||
| <IsTestProject>true</IsTestProject> | ||
| </PropertyGroup> | ||
|
|
||
| <ItemGroup> | ||
| <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0"/> | ||
| <PackageReference Include="NUnit" Version="3.13.3"/> | ||
| <PackageReference Include="NUnit3TestAdapter" Version="4.4.2"/> | ||
| <PackageReference Include="NUnit.Analyzers" Version="3.6.1"/> | ||
| <PackageReference Include="coverlet.collector" Version="3.2.0"/> | ||
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <ProjectReference Include="..\MyThreadPool\MyThreadPool.csproj" /> | ||
| </ItemGroup> | ||
|
|
||
| </Project> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,158 @@ | ||
| namespace MyThreadPool.Test; | ||
|
|
||
| public class MyThreadPoolTests | ||
| { | ||
| private class PoolTester | ||
| { | ||
| public int Counter { get; private set; } | ||
|
|
||
| public int Fst() | ||
| { | ||
| Counter++; | ||
| var result = 0; | ||
| for (int i = 0; i < 1000; i++) | ||
| { | ||
| result += i; | ||
| } | ||
|
|
||
| return result; | ||
| } | ||
| } | ||
|
|
||
| private static int TestFunc() | ||
| { | ||
| var result = 0; | ||
| for (int i = 0; i < 1000; i++) | ||
| { | ||
| result += i; | ||
| } | ||
|
|
||
| return result; | ||
| } | ||
|
|
||
| private MyThreadPool? _pool; | ||
| private int _processThreadsAmount; | ||
| private int _threadsAmount; | ||
|
|
||
| [SetUp] | ||
| public void Setup() | ||
| { | ||
| System.Diagnostics.Process.GetCurrentProcess().Refresh(); | ||
| this._processThreadsAmount = System.Diagnostics.Process.GetCurrentProcess().Threads.Count; | ||
| this._threadsAmount = 4; | ||
| this._pool = new MyThreadPool(this._threadsAmount); | ||
| } | ||
|
|
||
| [Test] | ||
| public void SubmitResultTest() | ||
| { | ||
| Assert.That(_pool!.Submit(TestFunc).Result, Is.EqualTo(499500)); | ||
| } | ||
|
|
||
| [Test] | ||
| public void SubmitContinueWithResultTest() | ||
| { | ||
| Assert.That(_pool!.Submit(TestFunc).ContinueWith((int result) => result + 1).Result, Is.EqualTo(499501)); | ||
| } | ||
|
|
||
| [Test] | ||
| public void DoubleContinueWithResultTest() | ||
| { | ||
| Assert.That(_pool!.Submit(TestFunc).ContinueWith((int result) => result + 1).ContinueWith((int result) => result.ToString()).Result, Is.EqualTo("499501")); | ||
| } | ||
|
|
||
| [Test] | ||
| public void SubmitResultContinueWithResultTest() | ||
| { | ||
| var task = _pool!.Submit(TestFunc); | ||
|
|
||
|
|
||
| Assert.That(task.ContinueWith((int result) => result + 1).Result, Is.EqualTo(499501)); | ||
| } | ||
|
|
||
| [Test] | ||
| public void LazyResultTest() | ||
| { | ||
| var tester = new PoolTester(); | ||
| var task = _pool!.Submit(tester.Fst); | ||
|
|
||
| var res = task.Result; | ||
| Assert.That(tester.Counter, Is.EqualTo(1)); | ||
| res = task.Result; | ||
| Assert.That(tester.Counter, Is.EqualTo(1)); | ||
| } | ||
|
|
||
| [Test] | ||
| public void ExceptionResultTest() | ||
| { | ||
| var tester = new PoolTester(); | ||
| var task = _pool!.Submit<int>(() => throw new NotImplementedException()); | ||
|
|
||
| Assert.Throws<AggregateException>(() => | ||
| { | ||
| var _ = task.Result; | ||
| }); | ||
| } | ||
|
|
||
| [Test] | ||
| public void IsCompletedTest() | ||
| { | ||
| var startEvent = new ManualResetEvent(false); | ||
| var task = _pool!.Submit(() => | ||
| { | ||
| startEvent.WaitOne(); | ||
| return TestFunc(); | ||
| }); | ||
|
|
||
| Assert.That(task.IsCompleted, Is.False); | ||
| startEvent.Set(); | ||
| var res = task.Result; | ||
| Assert.That(task.IsCompleted, Is.True); | ||
| res = task.Result; | ||
| Assert.That(task.IsCompleted, Is.True); | ||
| } | ||
|
|
||
| [Test] | ||
| public void ShutdownTest() | ||
| { | ||
| var fstTask = _pool!.Submit(TestFunc); | ||
| var secTask = _pool!.Submit(TestFunc); | ||
| _pool!.Shutdown(); | ||
| System.Diagnostics.Process.GetCurrentProcess().Refresh(); | ||
| Assert.That(System.Diagnostics.Process.GetCurrentProcess().Threads, Has.Count.EqualTo(_processThreadsAmount)); | ||
|
|
||
| Assert.Multiple(() => | ||
| { | ||
| Assert.That(fstTask.IsCompleted, Is.True); | ||
| Assert.That(secTask.IsCompleted, Is.True); | ||
| }); | ||
|
|
||
| _pool!.Submit(TestFunc); | ||
| fstTask.ContinueWith((int result) => result + 1); | ||
| System.Diagnostics.Process.GetCurrentProcess().Refresh(); | ||
| Assert.That(System.Diagnostics.Process.GetCurrentProcess().Threads, Has.Count.EqualTo(_processThreadsAmount)); | ||
| } | ||
|
|
||
| [Test] | ||
| public void DoubleContinueWithTest() | ||
| { | ||
| var fstTask = _pool!.Submit(TestFunc); | ||
| var fstContinueTask = fstTask.ContinueWith((int result) => result + 1); | ||
| var secContinueTask = fstTask.ContinueWith((int result) => result.ToString()); | ||
|
|
||
| Assert.Multiple(() => | ||
| { | ||
| Assert.That(fstContinueTask.Result, Is.EqualTo(499501)); | ||
| Assert.That(secContinueTask.Result, Is.EqualTo("499500")); | ||
| }); | ||
| } | ||
|
|
||
| [Test] | ||
| public void ThreadsCountTest() | ||
| { | ||
| System.Diagnostics.Process.GetCurrentProcess().Refresh(); | ||
| Assert.That(System.Diagnostics.Process.GetCurrentProcess().Threads, Has.Count.EqualTo(_processThreadsAmount + 4)); | ||
| } | ||
|
|
||
|
|
||
| } | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Не хватает тестов на конкурентный доступ к методам пула из нескольких потоков: submit задач из разных потоков, Submit и Shutdown одновременно, ContinueWith и Shutdown There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ➕ |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| global using NUnit.Framework; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| namespace MyThreadPool; | ||
|
|
||
| /// <summary> | ||
| /// Interface for my thread pool tasks | ||
| /// </summary> | ||
| /// <typeparam name="TResult">Task return value</typeparam> | ||
| public interface IMyTask<out TResult> | ||
| { | ||
| /// <summary> | ||
| /// Whether task is completed | ||
| /// </summary> | ||
| public bool IsCompleted { get; } | ||
|
|
||
| /// <summary> | ||
| /// Task result, blocks called thread | ||
| /// </summary> | ||
| /// <returns>task result</returns> | ||
| public TResult Result { get; } | ||
|
|
||
| /// <summary> | ||
| /// Continues task with given function, current task result is used as a parameter for the new one | ||
| /// </summary> | ||
| /// <param name="nextDelegate">New task delegate</param> | ||
| /// <typeparam name="TNewResult">New task return type</typeparam> | ||
| /// <returns>Returns created task</returns> | ||
| public IMyTask<TNewResult> ContinueWith<TNewResult>(Func<TResult, TNewResult> nextDelegate); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| namespace MyThreadPool; | ||
|
|
||
| public class MyThreadCreationException : Exception | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Надо комментарии |
||
| { | ||
| public MyThreadCreationException() | ||
| { | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Это не должно быть возможно после Shutdown по условию