Я бы лучше объяснил это в терминах, совершенно не связанных с компьютерами, поскольку зачастую это лучший способ донести идею.
У меня есть пятилетний сын и трехлетняя дочь. Оба хотят сделать одну и ту же книжку-раскраску.
Дочь хватает карандаши, а сын - книгу. Ни один из них не откажется от того, что у них есть, пока не получит другого.
Это тупик. Это не становится проще, чем это.
Ваши процессы (или дети) застряли в ожидании друг друга и будут продолжать ждать бесконечно долго, пока какой-нибудь другой вышестоящий процесс (например, папа) не войдет и не выйдет из тупика.
По крайней мере, с детьми вы можете (иногда) заставить одного из них увидеть причину и освободить их замок. Это обычно невозможно с компьютерами, поскольку процессы не делают ничего , кроме ожидания этого ресурса (хотя иногда дети также входят в это состояние).
Следование одному правилу гарантирует невозможность тупиковой ситуации:
Следование некоторым дополнительным правилам сделает ваши потоки менее вероятными для замедления друг друга, но имейте в виду, что вышеприведенное правило должно иметь приоритет над всеми остальными:
Пример для работы с
#!/usr/bin/python
country = 'fr'
#device = 'Sony_Ericsson-K750'
device = "Nokia N95 8Gb"
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
mmap_url = 'http://www.google.com/glm/mmap'
geo_url = 'http://maps.google.com/maps/geo'
from struct import pack, unpack
from httplib import HTTP
import urllib2
def fetch_latlong_http(query):
http = HTTP('www.google.com', 80)
http.putrequest('POST', '/glm/mmap')
http.putheader('Content-Type', 'application/binary')
http.putheader('Content-Length', str(len(query)))
http.endheaders()
http.send(query)
code, msg, headers = http.getreply()
result = http.file.read()
return result
def fetch_latlong_urllib(query):
headers = { 'User-Agent' : user_agent }
req = urllib2.Request(mmap_url, query, headers)
resp = urllib2.urlopen(req)
response = resp.read()
return response
fetch_latlong = fetch_latlong_http
def get_location_by_cell(cid, lac, mnc=0, mcc=0, country='fr'):
b_string = pack('>hqh2sh13sh5sh3sBiiihiiiiii',
21, 0,
len(country), country,
len(device), device,
len('1.3.1'), "1.3.1",
len('Web'), "Web",
27, 0, 0,
3, 0, cid, lac,
0, 0, 0, 0)
bytes = fetch_latlong(b_string)
(a, b,errorCode, latitude, longitude, c, d, e) = unpack(">hBiiiiih",bytes)
latitude = latitude / 1000000.0
longitude = longitude / 1000000.0
return latitude, longitude
def get_location_by_geo(latitude, longitude):
url = '%s?q=%s,%s&output=json&oe=utf8' % (geo_url, str(latitude), str(longitude))
return urllib2.urlopen(url).read()
if __name__ == '__main__':
print get_location_by_cell(20465, 495, 3, 262)
print get_location_by_cell(20442, 6015)
print get_location_by_cell(1085, 24040)
print get_location_by_geo(40.714224, -73.961452)
print get_location_by_geo(13.749113, 100.565327)
Как отмечалось в других обсуждениях, также посетите https://labs.ericsson.com/apis/mobile-location/documentation/cell-id-look-up-api для бесплатной базы данных идентификаторов сот для получения координат от cellid, mcc, mnc и lac.
Вы можете использовать Google Location API, который используется Firefox (пример см. на http://www.mozilla.com/en-US/firefox/geolocation/ ), который имеет url www.google.com/loc/json/. На самом деле это веб-сервис на основе JSON, и минимальный пример на Perl выглядит так:
use LWP;
my $ua = LWP::UserAgent->new;
$ua->agent("TestApp/0.1 ");
$ua->env_proxy();
my $req = HTTP::Request->new(POST => 'https://www.google.com/loc/json');
$req->content_type('application/jsonrequest');
$req->content('{"cell_towers": [{"location_area_code": "8721", "mobile_network_code": "01", "cell_id": "7703", "mobile_country_code": "262"}], "version": "1.1.0", "request_address": "true"}');
# Pass request to the user agent and get a response back
my $res = $ua->request($req);
# Check the outcome of the response
if ($res->is_success) {
print $res->content;
} else {
print $res->status_line, "\n";
return undef;
}
Пожалуйста, имейте в виду, что Google официально не открыл этот API для других применений...