2012-04-24 15 views
6

प्रश्न को और स्पष्ट करने के लिए संपादित किया गया।डार्ट श्रमिकों के रूप में पृथक

मैं डार्ट में Isolates (या वेब श्रमिक) के साथ काम करने की कोशिश कर रहा हूं। मुख्य और पृथक धागे के बीच संवाद करने के लिए एकमात्र तरीके मैं और को & पर कॉल कर सकता हूं तो मुख्य धागे से। लेकिन यह मुख्य धागे को कुछ डेटा को अलग करने के लिए एक अच्छा तरीका है।

क्या होगा यदि मैं जानकारी उत्पन्न करता हूं जो जानकारी उत्पन्न करता है? एक गेम इंजन की तरह जो एक कार्यकर्ता में सभी भौतिकी करता है और फिर मुख्य थ्रेड में एक अद्यतन दुनिया की जानकारी भेजता है? जावास्क्रिप्ट में आप किसी भी समय डेटा भेज सकते हैं। क्या डार्ट में कोई कुशल तरीका है? या क्या मुझे अभी भी मुख्य थ्रेड के लिए मुझे कॉल करने के लिए इंतजार करना है और फिर इसे पास करना है?

पीएस मुझे आश्चर्य है, कॉल & पर उत्तर तक पूरा होने तक धागा को अवरुद्ध करता है या नहीं?

उत्तर

3

चेतावनी: यह कोड केवल डार्ट के बहुत पुराने संस्करणों पर काम करता है। यह डार्ट 1.0 या बाद में काम नहीं करता है।

जैसा कि आप एक अलग करने के लिए संदेश पोस्ट करने का उल्लेख करते हैं, आपको इसके प्रेषण पर एक संभाल करने की आवश्यकता है।

#import('dart:isolate'); 

main() { 
    SendPort sendPort = spawnFunction(doWork); 
    sendPort.call("hey 1").then((String res) => print("result was: [$res]")); 
    sendPort.call("hey 2").then((String res) => print("result was: [$res]")); 
} 

doWork() { 
    port.receive((msg, reply) { 
    msg = "msg $msg"; 
    reply.send(msg); 
    }); 
} 

तथापि के बाद से डार्ट मुख्य थ्रेड अपने आप में एक अलग आप वैश्विक बंदरगाह फ़ंक्शन का उपयोग करके यह करने के लिए डेटा भेज सकते हैं:

#import('dart:isolate'); 
#import('dart:io'); 

main() { 
    port.receive((data, reply) { 
     // in here you can access objects created in the main thread 
     print("handle [${data['text']}] for index ${data['index']}"); 
    }); 

    SendPort workPort = spawnFunction(doWork); 
    workPort.send("msg", port.toSendPort()); 
} 

doWork() { 
    port.receive((msg, reply) { 
     int i = 0; 
     new Timer.repeating(1000, (Timer timer) { 
     i++; 
     var data = { 
      "text": "$msg $i", 
      "index": i 
     }; 
     print("sending $data"); 
     reply.send(data); 
     }); 
    }); 
} 

नोट वहाँ क्या वापस भेज किया जा सकता है के बारे में कुछ सीमाएं हैं और अलग-अलग के बीच और वर्तमान में जेएस और वीएम में अलग-अलग कार्य को अलग करता है। वर्तमान सीमाएं अच्छी तरह से वर्णित हैं here

+0

लेकिन क्या उत्पन्न करने के लिए मेरी अलग करता है, तो मैं चाहता हूँ है/अद्यतन डेटा? एक गेम इंजन की तरह। यह माना जाता है कि सभी गणनाएं चलती हैं और फिर ऑब्जेक्ट में ऑब्जेक्ट की अद्यतन स्थिति पास करती हैं। क्या इसके लिए कोई कुशल तंत्र है या क्या मुझे इसे अलगाव के शीर्ष पर बनाना है? – Pijusn

+0

@Pius आप एक अलग में संदर्भ नहीं भेज सकते हैं, यहां वर्णित सभी डेटा कॉपी किए गए हैं http://api.dartlang.org/dart_isolate/SendPort.html#send –

+0

मैं संदर्भों के बारे में बात नहीं कर रहा हूं। मैं डेटा के बारे में बात कर रहा हूँ। क्या आपने कभी जावास्क्रिप्ट में वेब वर्कर्स के साथ कार्यकर्ता है? आप किसी भी समय कार्यकर्ता से डेटा भेज सकते हैं। और जितना चाहें उतना। कार्यकर्ता मुख्य थ्रेड को सुनने के बिना भी काम कर सकता है और डेटा भेज सकता है जबकि मुख्य धागा कॉलबैक फ़ंक्शन का उपयोग करके डेटा प्राप्त कर सकता है। मैं अलग-अलग में self.postMessage फ़ंक्शन के बारे में बात कर रहा हूं। – Pijusn

0

अब आप MessageBox कक्षा का उपयोग अन्य तरीकों से संवाद करने के लिए कर सकते हैं। यह कोड Isolate कोड से संदेश भेजता है जैसे ही इसे संदेशबॉक्स का सिंक अंत प्राप्त होता है। मुख्य धागे को पृथक से भेजे गए संदेश प्राप्त होते हैं और इसे डार्टियम के कंसोल पर प्रिंट करते हैं। एक बार जब आप सिंक प्राप्त कर लेते हैं तो आप अपना गेम लॉजिक लॉन्च कर सकते हैं और प्राप्त सिंक ऑब्जेक्ट का उपयोग करके अपडेट भेज सकते हैं।

import 'dart:html'; 
import 'dart:isolate'; 

void main() { 
    IsolateSink isolateSink = streamSpawnFunction(myIsolateEntryPoint); 
    MessageBox isolateMessageBox = new MessageBox(); 
    isolateSink.add(isolateMessageBox.sink); 
    isolateMessageBox.stream.listen((String data) { 
    print(data); 
    }); 
} 

void myIsolateEntryPoint() { 
    stream.listen((IsolateSink messageBoxSink) { 
    messageBoxSink.add("Test"); 
    }); 
} 
3

डार्ट 1.0 के रूप में, आप उपयोग कर सकते हैं इस तरह अलग कर:

import 'dart:isolate'; 
import 'dart:async'; 

void doStuff(SendPort sendPort) { 
    print('hi from inside isolate'); 
    ReceivePort receivePort = new ReceivePort(); 
    sendPort.send(receivePort.sendPort); 

    receivePort.listen((msg) { 
    print('Received in isolate: [$msg]'); 
    sendPort.send('ECHO: $msg'); 
    }); 

} 

void main() { 
    SendPort sendPort; 

    ReceivePort receive = new ReceivePort(); 
    receive.listen((msg) { 
    if (sendPort == null) { 
     sendPort = msg; 
    } else { 
     print('From isolate: $msg'); 
    } 
    }); 

    int counter = 0; 

    Isolate.spawn(doStuff, receive.sendPort).then((isolate) { 
    new Timer.periodic(const Duration(seconds:1), (t) { 
     sendPort.send('Count is ${counter++}'); 
    }); 
    }); 
} 
1

एक उदाहरण है जहाँ माता-पिता दो आइसोलेट्स बनाता है और फिर दो आइसोलेट्स भी माता-पिता की प्रक्रिया के साथ-साथ एक दूसरे से बात है।

जनक कोड:

import 'dart:isolate'; 
import 'dart:html'; 
import 'dart:async'; 

main() { 
    querySelector('#output').text = 'Your Dart app is running.'; 
    int counter = 0; 

    // Parent - Child 1 
    SendPort csendPort1; 
    ReceivePort receivePort1 = new ReceivePort(); 
    // Parent - Child 2 
    SendPort csendPort2; 
    ReceivePort receivePort2 = new ReceivePort(); 
    // Child1 - Child2 
    SendPort csendPort11; 
    SendPort csendPort12; 

    // Child 1 
    receivePort1.listen((msg) { 
    if (csendPort1 == null) { 
     csendPort1 = msg; 
    } else if (csendPort11 == null) { 
     csendPort11 = msg; 
    } else { 
     print('$msg');`enter code here` 
    } 
    }); 

    bool child1 = false; 
    Isolate.spawnUri(Uri.parse('child.dart'), [], receivePort1.sendPort).then((isolate) { 
    print('Child 1 isolate spawned'); 
    new Timer.periodic(const Duration(milliseconds: 500), (t) { 
     if (csendPort11 != null && csendPort12 != null && child1 == false) { 
     child1 = true; 
     csendPort12.send(csendPort11); 
     } else { 
     csendPort1.send('Parent-Child1: ${counter++}'); 
     } 
    }); 
    }); 

    // Child 2 
    receivePort2.listen((msg) { 
    if (csendPort2 == null) { 
     csendPort2 = msg; 
    } else if (csendPort12 == null) { 
     csendPort12 = msg; 
    } else { 
     print('$msg'); 
    } 
    }); 

    bool child2 = false; 
    Isolate.spawnUri(Uri.parse('child.dart'), [], receivePort2.sendPort).then((isolate) { 
    print('Child 2 isolate spawned'); 
    new Timer.periodic(const Duration(milliseconds: 500), (t) { 
     if (csendPort11 != null && csendPort12 != null && child2 == false) { 
     child2 = true; 
     csendPort11.send(csendPort12); 
     } else { 
     csendPort2.send('Parent-Child2: ${counter++}'); 
     } 
    }); 
    }); 
} 

बाल कोड:

import 'dart:isolate'; 
import 'dart:async'; 

int pcounter = 0; 
int ccounter = 0; 

SendPort csendPort; 
void handleTimeout() { 
    csendPort.send("${ccounter++}"); 
} 

main(List<String> args, SendPort psendPort) { 
    // Parent Comm 
    ReceivePort creceivePort1 = new ReceivePort(); 
    psendPort.send(creceivePort1.sendPort); 

    creceivePort1.listen((msg) { 
    psendPort.send('Child-Parent: ${pcounter++} - ${msg}'); 
    }); 

    // Child-Child Comm 
    ReceivePort creceivePort2 = new ReceivePort(); 
    psendPort.send(creceivePort2.sendPort); 

    creceivePort2.listen((msg) { 
    if (csendPort == null) { 
     csendPort = msg; 
     csendPort.send("${ccounter++}"); 
    } else { 
     print("Child-Child: $msg"); 
     var duration = const Duration(milliseconds: 2000); 
     new Timer(duration, handleTimeout); 
    } 
    }); 
} 

एचटीएमएल कोड:

<!DOCTYPE html> 
<html> 
<head> 
    <meta charset="utf-8"> 
    <meta http-equiv="X-UA-Compatible" content="IE=edge"> 
    <meta name="viewport" content="width=device-width, initial-scale=1.0"> 
    <meta name="scaffolded-by" content="https://github.com/google/stagehand"> 
    <title>WebIsolateTest</title> 
    <link rel="stylesheet" href="styles.css"> 
    <script defer src="main.dart" type="application/dart"></script> 
    <script defer src="packages/browser/dart.js"></script> 
</head> 

<body> 

    <div id="output"></div> 

</body> 
</html> 
+0

उपरोक्त कोड डार्ट एसडीके संस्करण 1.14.2 और क्रोम, फ़ायरफ़ॉक्स और आईई 11 पर काम करता है – user2569304

संबंधित मुद्दे