Программа Python с помощью os.pipe и os.fork () проблема

С помощью плагина Geocoder вы можете получить адрес по широте и долготе

getUserLocation() async {//call this async method from whereever you need

      Map currentLocation = new Map();
      Map myLocation;
      String error;
      Location location = new Location();
      try {
        myLocation = await location.getLocation();
      } on PlatformException catch (e) {
        if (e.code == 'PERMISSION_DENIED') {
          error = 'please grant permission';
          print(error);
        }
        if (e.code == 'PERMISSION_DENIED_NEVER_ASK') {
          error = 'permission denied- please enable it from app settings';
          print(error);
        }
        myLocation = null;
      }
      currentLocation = myLocation;
      final coordinates = new Coordinates(
          currentLocation['latitude'], currentLocation['longitude']);
      var addresses = await Geocoder.local.findAddressesFromCoordinates(
          coordinates);
      var first = addresses.first;
      print(' ${first.locality}, ${first.adminArea},${first.subLocality}, ${first.subAdminArea},${first.addressLine}, ${first.featureName},${first.thoroughfare}, ${first.subThoroughfare}');
      return first;
    }

10
задан Eliyahu 27 July 2014 в 11:15
поделиться

4 ответа

Are you using read() without specifying a size, or treating the pipe as an iterator (for line in f)? If so, that's probably the source of your problem - read() is defined to read until the end of the file before returning, rather than just read what is available for reading. That will mean it will block until the child calls close().

In the example code linked to, this is OK - the parent is acting in a blocking manner, and just using the child for isolation purposes. If you want to continue, then either use non-blocking IO as in the code you posted (but be prepared to deal with half-complete data), or read in chunks (eg r.read(size) or r.readline()) which will block only until a specific size / line has been read. (you'll still need to call flush on the child)

It looks like treating the pipe as an iterator is using some further buffer as well, for "for line in r:" may not give you what you want if you need each line to be immediately consumed. It may be possible to disable this, but just specifying 0 for the buffer size in fdopen doesn't seem sufficient.

Heres some sample code that should work:

import os, sys, time

r,w=os.pipe()
r,w=os.fdopen(r,'r',0), os.fdopen(w,'w',0)

pid = os.fork()
if pid:          # Parent
    w.close()
    while 1:
        data=r.readline()
        if not data: break
        print "parent read: " + data.strip()
else:           # Child
    r.close()
    for i in range(10):
        print >>w, "line %s" % i
        w.flush()
        time.sleep(1)
12
ответ дан 4 December 2019 в 00:26
поделиться

Использование

fcntl.fcntl (readPipe, fcntl.F_SETFL, os.O_NONBLOCK)

Перед вызовом read () решило обе проблемы. Вызов read () больше не блокируется, и данные появляются только после flush () на стороне записи.

5
ответ дан 4 December 2019 в 00:26
поделиться

Я вижу, вы решили проблему блокировки ввода-вывода и буферизации.

Примечание, если вы решите попробовать другой подход: подпроцесс эквивалентен / заменяет вилку / exec идиома. Похоже, что это не то, что вы делаете: у вас есть просто вилка (не exec) и обмен данными между двумя процессами - в этом случае модуль multiprocessing (в Python 2.6+) будет лучше подходит.

4
ответ дан 4 December 2019 в 00:26
поделиться

Родительский "Против" "дочерней" части вилки в приложении Python глупо. Это наследие 16-битных времен Unix. Это эффект того дня, когда fork / exec и exec были важными вещами, позволяющими максимально использовать крошечный процессор.

Разделите код Python на две отдельные части: родительскую и дочернюю.

Родительская часть должна использовать

1134416] подпроцесс для запуска дочерней части.

-9
ответ дан 4 December 2019 в 00:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: