0

I understand task as task in C#, but this questions is not related to C#.

Let's say I have single thread and two tasks (both CPU-bound). I would like to run them concurrently, without running one of them at the expense of starving completely the other one. How this could be implemented without assuming the code will somehow cooperate?

Is it possible to set some kind of timeout (or instruction countdown) on CPU/OS level to freeze task with its entire stack, and run the other task in the same manner, then resume the first one and so on?

This question does not go to level of multitasking with threads. It is about multitasking within single, one, thread. Task is not the same as thread.

greenoldman
  • 1,506
  • 1
  • 14
  • 27
  • 1
    Possible duplicate of [How is it possible to have limitless availability of threads while only having a finite number of physical processing units?](https://softwareengineering.stackexchange.com/questions/355769/how-is-it-possible-to-have-limitless-availability-of-threads-while-only-having-a) (Or close, anyway.) – Blrfl Dec 24 '17 at 14:26
  • @Blrfl, I don't see relevance here. Think about one core, one CPU, one thread, only multiple tasks. So I am above the level of thread (and the other question asks about them). Or from other perspective -- how one could implement task scheduler in C# with task switching but without awaits (i.e. point indicators of switching). – greenoldman Dec 24 '17 at 15:24
  • How do you think what you're asking wouldn't be a reinvention of the same wheels described in the answer to that question? – Blrfl Dec 24 '17 at 17:42
  • 1
    I realize you've already selected an answer, but I'm curious as to why a single thread is a requirement here? ... Are you hoping to manage job unit scheduling or "task" throttling yourself in some way? ... Are you somehow trying to avoid the concurrency risks that come with threading? ... Are you working with a specific language or technology stack? Or, are you looking for a general pattern that is technology independent? – svidgen Dec 24 '17 at 20:26
  • @svidgen, pretty basic, if multithread was not excluded, I would get answer "just put one task per a thread, solved". I am asking in context of writing task scheduler by myself, not language specific, just general pattern. – greenoldman Dec 25 '17 at 07:08
  • @Nat, "that solution'd kinda be a de facto hammer," you cannot be sure until you see the answer. And I prefer to ask instead of base on incorrect assumptions. It is how do we (at least me) learn, isn't it? :-) The fact C# thread is not OS thread, does not make them automatically fibers, to that they would need injected points of switch. – greenoldman Dec 25 '17 at 07:11
  • I'm curious as to why the selected answer was selected then... It'd be much less inefficient than simply using threads, but nothing prevents you from creating your own `Task` and `UnitOfWork` classes (or whatever). You could easily create workers that only process units of a task on the receipt of a heartbeat, controlled by a main loop... Right? – svidgen Dec 25 '17 at 13:21
  • @svidgen, answer "it is not possible" is valid and informative for me. It means that for CPU-bound "tasks" I have to use entire thread, in other words task scheduler has to know in advance (from user) if the user wants a task or a thread. I don't follow how I could create efficiently workers and not freeze entire program, please keep in mind that user won't give you switch points. So once I start computing it is computation all along. – greenoldman Dec 25 '17 at 20:22
  • It's still really not clear in the question what practical problem you're trying to solve. Hence, it is still unclear (to me) why the selected answer actually answers the question -- whereas Cort's fibers isn't "correct" -- or why some other homegrown unit-of-work scheduling algorithm (even a sort of VM, if you like) *wouldn't* be a good answer ... – svidgen Dec 25 '17 at 21:13
  • @svidgen, on SO you can accept only one answer as solution, I upvoted both answers, but I cannot accept both from the technical reason not because the other one is incorrect. Let's say I have 2 pieces of code, both very CPU demanding, if I run them in the same thread, I am toasted, because they won't switch. How "unit of work" will help here? And practical problem -- I already wrote, I am about to write task scheduler and I wanted to know if it is possible to write it in general way, i.e. without hinting scheduler what kind of job it is, CPU-bound, or I/O-bound. – greenoldman Dec 26 '17 at 07:07
  • You're asking for a particular solution without really stating the problem -- like why these tasks can't be run in threads. Or why they can't cooperate. This is an [XY problem](http://xyproblem.info/)... Might even be off topic here as-asked. ... Further complicating it, the hypothetical solution in your answer sounds like... Err ... ***Threading***... – svidgen Dec 26 '17 at 17:04
  • Anywho. The "unit of work" was meant to imply cooperation. But, if your tasks are simple and predictable, you can implement your own stack and either a DSL (like an inner scripting language), a micro-VM, or just structure your tasks to perform *N* operations before returning to the scheduler (i.e., cooperate...). **Or** ... Use threads. I still don't understand why threads aren't an option! AFAIK, there are frameworks for many languages that will give you "tasks" and hide thread pools behind the scenes -- my *intuition* is that you ultimately just want threads without knowing about them... – svidgen Dec 26 '17 at 17:57
  • @svidgen, with due all respect, I asked the question (I rephrase it for you briefly "what are other means for job-switching other than fibers and threads and I/O multiplexing"), I got my answers (so there is proof somebody understood it), the only person with problem is now you -- I answered what my goal is, and you keep repeating exactly the same concern over and over again. Thank you for your input, but further answering is futile so I stop here. – greenoldman Dec 27 '17 at 07:32
  • Good for you. This is a*public* QA site though. As important as it is that you feel served by the community, it's your duty to ensure your contributions *serve* the community. We have question quality guidelines, not for the purpose of the OP's, but for *everyone else.* ... Voting to close. – svidgen Dec 27 '17 at 14:08

2 Answers2

3

The feature you are looking for is "fibers," sometimes called "cooperative threads." A fiber has its own stack, but you switch them in-and-out of threads cooperatively. Any one fiber can call a function, typically called yield, and pass the fiber that they wish the computer to execute on this thread. Only one fiber executes at one time on a given thread, and nothing can stop it from executing involuntarily -- it needs to call a yield function to cooperatively give away control.

I'm not certain if C# has fiber support. Fibers were never very popular, and it seems like a feature which will raise a lot of challenges for a managed language. But that's the feature you're looking for.

How to do it without cooperation between the algorithms? That answer is easy: the sole entire purpose of threads is to do exactly the thing you want to do, because you need OS help to do it. Threads take advantage of a timer that fires at the OS level every few milliseconds, and their knowledge of how their stack is constructed to do the exact thing you want to do.

The reason OS libraries support threads is because you cannot do this on your own without either the cooperation of the OS (threads) or the cooperation of your other algorithms (fibers).

Robert Harvey
  • 198,589
  • 55
  • 464
  • 673
Cort Ammon
  • 10,840
  • 3
  • 23
  • 32
1

No, that is not possible.

On the CPU/OS level, multitasking is executed on the level of threads. The OS gives time to various threads, but doesn't know about the (more granular) concept of tasks.

Bart van Ingen Schenau
  • 71,712
  • 20
  • 110
  • 179