Подтвердить что ты не робот

Может ли многопоточность быть реализована на одной процессорной системе?

Я всегда придерживался концепции, согласно которой многопоточность может быть реализована только в нескольких системах процессоров, где каждому потоку назначено более одного процессора, и каждый поток может выполняться одновременно. В этом случае планирование не выполняется, так как каждый поток имеет отдельные ресурсы, предназначенные для него. Но я где-то читал, что могу многопоточно работать и на однопроцессорной системе. Правильно ли это? и если да, то в чем разница между одним процессором и несколькими процессорными системами?

4b9b3361

Ответ 1

Конечно, это можно сделать на однопроцессорной системе, и на самом деле это намного проще. Он работает так же, как запуск нескольких процессов - ядро, посредством прерывания таймера или другого аналогичного механизма, приостанавливает его, сохраняет состояние своего компьютера и заменяет его ранее сохраненным состоянием другого - единственная разница состоит в том, что два потоки одного и того же процесса используют одно и то же пространство виртуальной памяти, что делает задачу-коммутатор более эффективной.

Многопоточность на многопроцессорных системах на самом деле намного сложнее, поскольку у вас есть проблемы одновременного доступа к памяти из нескольких процессоров/процессоров и всех неприятных проблем синхронизации памяти, которые возникают из этого.

Ответ 2

Я прочитал его где-нибудь, что могу многопоточно работать на одном процессорной системы. Правильно ли это? и если да, то что разница между одним процессором и несколькими процессорными системами?

Да, вы можете выполнять многопоточность в одной процессорной системе.

В многопроцессорной системе выполняется несколько потоков, одновременно на разных ядрах. Например: если есть два потока и два ядра, каждый поток будет работать на отдельном ядре.

В однопроцессорной системе несколько потоков выполняются один за другим или ждут, пока один поток закончит или будет выгружен ОС, в зависимости от приоритета потока и политики ОС. Но запущенные потоки создают иллюзию, что они работают одновременно, относительно требуемого времени отклика приложения приложения пространства пользователя.

Сравнение времени (пример):

если два потока принимают по 10 штук каждый, чтобы выполнить, то в 2-процессорной системе, нетто время занимает 10us

если два потока принимают по 10 штук каждый, чтобы выполнить, то в 1 процессорной системе, нетто время занимает 20us

Ответ 3

У вас может быть более четырех активных потоков в четырехъядерной системе. Существует планирование, если вы не можете гарантировать, что процессы не будут пытаться создавать больше потоков, чем есть процессоры.

Да, вы можете иметь несколько потоков на одноядерном компьютере.

Разница между однопроцессорными и многопроцессорными системами заключается в том, что многопроцессорная система действительно может делать больше, чем одна вещь за раз. Он может делать N вещей за раз, где N - количество процессорных ядер. Однопроцессорное ядро ​​может делать только одно за раз. Как сказал в своем комментарии WhozCraig, это разница между фактическим и воспринимаемым concurrency.

Ответ 4

Вот очень упрощенный пример. Это фактически прототип для программы, которую я создаю. Это реализация совместной многозадачности в одном потоке.

main просто устанавливает флаг quit в значение false и заполняет массив указателей функций (задач), а затем вызывает loop.

loop использует setjmp для установки точки возврата для нелокального перехода (переход из функции обратно в предыдущее место при выполнении), а затем переходит к вызову первой задачи (функции).

Каждая задача заканчивается на yield(). То есть ни одна из функций задачи фактически return. Они не только не содержат оператора return; (это было бы хорошо, поскольку они были void функциями, т.е. Процедурами), но они не достигли return, даже если бы он был там, потому что yield отскакивает назад на вызов setjmp, на этот раз вывод 1 в оператор if в loop. Операция, управляемая оператором if, выбирает другую задачу перед повторным вводом цикла while.

Поэтому каждая функция задачи выполняется несколько раз, что приводит к диспетчеру (оператор if(setjmp...), который выбирает новую задачу для запуска.

#include <stdio.h> 
#include <setjmp.h> 

jmp_buf dispatch; 
int ntasks; 
void (*task[10])(void); 
int quit; 

void yield(void) { 
    longjmp(dispatch, 1); 
} 

void loop() { 
    static int i = 0; 
    if(setjmp(dispatch)) 
        i = (i+1) % ntasks; 
    while(!quit) 
        task[i](); 
} 

int acc = 0; 

void a(void) { 
    if (acc > 10) quit = 1; 
    printf("A\n"); 
    yield(); 
} 
void b(void) { 
    acc *= 2; 
    printf("B\n"); 
    yield(); 
} 
void c(void) { 
    acc += 1; 
    printf("C\n"); 
    yield(); 
} 

int main() { 
    quit = 0; 
    ntasks = 3; 
    task[0] = a; 
    task[1] = b; 
    task[2] = c; 
    loop(); 
    return 0; 
} 

Разница между этим примером и однопроцессорной многозадачной компьютерной системой заключается в том, что реальный процессор поддерживает прерывание задачи в середине выполнения и возобновление ее позже с того же места. Это невозможно сделать в симуляторе C с заданиями в виде одиночных функций. Однако задачи могут состоять из последовательности C-функций, каждая из которых дает диспетчер (массив указателей на функции, возможно, или связанный список).

Ответ 5

Да, вы полностью можете. Возрасты назад (Win 95?) Мы перешли от совместной многозадачности к многопоточности, потому что кто-то всегда прикручивал кооперативную часть. Каждая программа на вашем компьютере имеет хотя бы один поток. Возможно, больше. И процессор поддерживает только переключение между теми, что все эти темы, как безумные несколько миллионов раз в секунду. Если ни один из них не имеет ничего общего, он может даже простаивать некоторое время.

Многоядерные системы означают только то, что два или более из этих потоков могут выполняться в паралелях.

Однако это приносит вам гораздо меньше. Все, что вы можете сделать с помощью многопоточности на машине с одним ядром, - это симуляция многозадачности.

Mulitasking достаточно, чтобы предотвратить зависание потока GUI из-за долговременной работы. Однако, как правило, это сложно реализовать, если у вас нет какой-либо помощи от компилятора или Langauge (например, С# async... await). В результате многие программисты GUI просто использовали Multithreading и Invoking для подделки многозадачности. Если этот код работает на одном или нескольких ядрах, для этого не требуется.

Самое главное, многозадачность НЕ подходит для операций с привязкой к ЦП. Но 95% всех проблем с Async не связаны с ЦП. Они связаны с сетью или дисками. На однопользовательском компьютере многопоточность также не помогает связанным с ЦП компонентам. Если у вас есть два потока, для которых требуется 100% процессорного времени (одна и та же программа или другая), но только одно ядро ​​для их запуска, то CPU просто придется переключаться между хостом как на 49%, так и на оставшиеся 2% для всех этих другие потоки, которые делают только немного.

Наконец, очень немногие проблемы могут быть многопоточными. Просто попробуйте многопоточную последовательность Fibonacci (один поток для каждой пары), не делая ее медленнее, больше требующей памяти и более сложной.

ТЛ; дг; Вам нужно многопоточность и многопользовательский компьютер для проблем с привязкой к ЦП. Большинство асинхронных проблем не связаны с ЦП. Многозадачность достаточно. И вы можете полностью многозадачно использовать потоки, даже на одной основной машине.