Результаты поиска
Найдено результатов: 8
Удобный трединг в Javascript?
Приветствую.
На самом деле, речь не совсем о трединге. Да, в Javascript «чистого» трединга вроде как нету, но есть ещё webworkers, это я знаю, а здесь я хочу поднять вопрос о другом. Для начала я уточню, что конкретно я буду подразумевать под «тредингом».
Типичная задача следующая. Есть некий код (для определённости, врапнутый в функцию myFunc) и я хочу запустить этот код неким вызовом, но при этом не дожидаясь завершения этого вызова перейти к следующей строке кода, откуда я этот вызов совершаю. Обычно эта задача решается примерно таким образом:
setTimeout( myFunc, 10 );
doSomethingElse();
где myFunc() содержит код, который я хочу выполнить «в треде», а doSomethingElse() содержит код, про который я хочу чтобы он начал выполняться, не дожидаясь завершения myFunc(). А если мне нужно вызвать функцию myFunc() как метод объекта — я могу заюзать замыкание и apply(), обернув это в ещё одну анонимную функцию.
Самое загадочное в таком подходе — второй аргумент функции setTimeout(). Почему я сказал ей выполнить код через 10 милисекунд, а не сразу — через 0? Люди пишут (комменты), что setTimeout(fn, 0) часто работает дольше, чем setTimeout(fn, 10). И там же предлагается ещё более быстрый способ «заказать» асинхронное выполнение функции «прямо сейчас», с использованием postMessage.
Я решил немного поэкспериментировать с приведённым там кодом и сделать его чуть более удобным. Идея состоит в том, что прототипу объекта типа Function добавляется новый метод thread(), который запускает эту функцию асинхронно и форвардит ей все аргументы. Получилось примерно так:
(function() {
var threads = [];
var messageName = "start-thread";
function thread(fn) {
threads.push(fn);
window.postMessage(messageName, "*");
}
function startThread(event) {
if (event.source == window &&
event.data == messageName) {
event.stopPropagation();
if (threads.length> 0) {
( threads.shift() )();
}
}
}
window.addEventListener("message", startThread, true);
Function.prototype.thread = function() {
var args = arguments;
var me = this;
thread(
function() {
me.apply( null, args );
}
);
}
})();
var doSomething = function(a, b) {
alert( a + b );
}
// вызываем doSomething() асинхронно:
doSomething.thread( 2, 3 );
В общем, это практически точная копия кода по ссылке, плюс новый метод thread объектам типа Function.
И теперь внимание вопрос. Для того, чтобы метод thread был действительно удобным, нужно иметь возможность использовать его для методов объектов. То есть, каким-то образом в функцию thread нужно «протащить» информацию об объекте, в контексте которого мы обратились к методу. Использование замыкания напрочь испортит всю элегантность. Хочется пользоваться этим методом примерно так:
myObject.myMethod.thread( arg1, arg2 );
и в результате такого вызова метод myMethod должен вызваться асинхронно в контексте объекта myObject, то есть должно произойти
myObject.myMethod.apply( myObject, [ arg1, arg2 ] );
Возможно ли это?
setTimeout( myFunc, 10 );
doSomethingElse();(function() {
var threads = [];
var messageName = "start-thread";
function thread(fn) {
threads.push(fn);
window.postMessage(messageName, "*");
}
function startThread(event) {
if (event.source == window &&
event.data == messageName) {
event.stopPropagation();
if (threads.length> 0) {
( threads.shift() )();
}
}
}
window.addEventListener("message", startThread, true);
Function.prototype.thread = function() {
var args = arguments;
var me = this;
thread(
function() {
me.apply( null, args );
}
);
}
})();
var doSomething = function(a, b) {
alert( a + b );
}
// вызываем doSomething() асинхронно:
doSomething.thread( 2, 3 );myObject.myMethod.apply( myObject, [ arg1, arg2 ] );
Многопоточные приложения на C++ под Linux?
Собственно говоря, есть интерес и подвернулись лабораторные работы, но самостоятельно не смог найти книг хорошо раскрывающих тему.
Я думаю что тут есть достаточно подкованные в этом вопросе люди. Прошу помочь подобрать список литературы.
Многопоточное программирование?
Где бы почитать про эту вещь в хорошем теоретическом аспекте, где были бы освещены паттерны, примеры, проблемы, хитрости и тому подобное?
Желательно в применении к Python, но это не столь важно, куда важнее получить базис.
А то пытаюсь реализовать некоторые вещи, а понимаю, что не знаю основ проектирования многопоточных приложений и создается ощущение, что клею обои через замочную скважину.
MySQL — Синхронизация нескольких потоков
Имеется задача: вставить N элементов в таблицу, но перед этим удостовериться, не добавлены ли уже такие элементы.
Т.е. сначала делаем что-то вроде:
SELECT COUNT(*) FROM xxx WHERE x IN (x1,x2,x3,x4,x5,x6…… x1000);
Если результат равен 0, то значит можно делать такой же массовый INSERT.
Но есть проблема — как сделать это секурно при многопоточности?
Т.е., допустим, как избежать ситуации, когда одновременно получаются 2 потока и порядок действий получается таким:
П1: SELECT COUNT(*) — получает «0»
П2: SELECT COUNT(*) — получает «0»
П1: делает INSERT
П2: т.к. получил «ноль» в предыдущем селекте, тоже делает INSERT дублирующих записей
Есть ли решение для такой задачи?
Идея выставлять какой-то глобальный флаг кажется очень кривой и глупой.
Хранимки не предлагайте, т.к. опять-таки — они не спасут от одновременности. Как вообще такие вещи делаются?
Вставлять предполагается порой большие массивы данных по несколько десятков тысяч, так что вероятно, что запросы будут выполняться не слишком быстро и есть вероятность словить баг с одновременной вставкой.
Задачка на многопоточность (.NET)?
Какая проблема есть в коде? Как изменить код так, чтобы ее избежать?
using System;
using System.Threading;
namespace Mover
{
internal class Endpoint
{
public int Amount { get; set; }
}
internal class Program
{
private static void Main(string[] args)
{
var source = new Endpoint();
var target = new Endpoint();
var initialAmount = 1000000;
source.Amount = initialAmount;
var thread = new Thread(new ThreadStart(delegate
{
Transfer(source, target, initialAmount);
}));
thread.Start();
Transfer(target, source, initialAmount / 2);
thread.Join();
Console.Out.WriteLine("source.Amount = {0}", source.Amount);
Console.Out.WriteLine("target.Amount = {0}", target.Amount);
}
private static void Transfer(Endpoint source, Endpoint target, int count)
{
while (count-- > 0)
lock (target)
lock (source)
{
source.Amount--;
target.Amount++;
}
}
}
}
using System;
using System.Threading;
namespace Mover
{
internal class Endpoint
{
public int Amount { get; set; }
}
internal class Program
{
private static void Main(string[] args)
{
var source = new Endpoint();
var target = new Endpoint();
var initialAmount = 1000000;
source.Amount = initialAmount;
var thread = new Thread(new ThreadStart(delegate
{
Transfer(source, target, initialAmount);
}));
thread.Start();
Transfer(target, source, initialAmount / 2);
thread.Join();
Console.Out.WriteLine("source.Amount = {0}", source.Amount);
Console.Out.WriteLine("target.Amount = {0}", target.Amount);
}
private static void Transfer(Endpoint source, Endpoint target, int count)
{
while (count-- > 0)
lock (target)
lock (source)
{
source.Amount--;
target.Amount++;
}
}
}
}