Nachtrag (25.10.2016): 10.2.1 wurde veröffentlicht, aber es scheint, dass sich die Situation in diesem Fall nicht verbessert hat. Nachtrag (31.03.2017): Bestätigt in 10.12.4. Es scheint, dass es behoben wurde. Du hast es geschafft!
sqlite3_sierra_exp.py
#!/usr/bin/env python
"""\
An example that crashes on macOS Sierra.
"""
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from logging import getLogger, StreamHandler, Formatter
from logging import DEBUG
from multiprocessing import Process, freeze_support
from threading import Thread
import os
import sqlite3
import sys
import time
_DB_PATH = os.path.join(os.path.dirname(__file__), 'state.db')
def _connect(db_path):
conn = sqlite3.connect(db_path)
return conn
def get_count(db_path, name):
conn = _connect(db_path)
c = conn.cursor()
c.execute('''\
SELECT count FROM test_table
WHERE name = ?
''', (name,))
(count,) = c.fetchone()
conn.commit()
conn.close()
return count
def incrementer_process(db_path, name):
conn = _connect(db_path)
c = conn.cursor()
c.execute('''\
SELECT count FROM test_table
WHERE name = ?
''', (name,))
(count,) = c.fetchone()
c.execute('''\
INSERT OR REPLACE INTO test_table
(name, count)
VALUES (?, ?)
''', (name, count + 1))
conn.commit()
conn.close()
def main():
logger = getLogger(__name__)
handler = StreamHandler()
logger.addHandler(handler)
logger.setLevel(DEBUG)
handler.setLevel(DEBUG)
handler.setFormatter(Formatter('%(asctime)s %(message)s'))
logger.info('python version: {}'.format(sys.version))
logger.info('module_version: {}'.format(sqlite3.version))
logger.info('sqlite3_version: {}'.format(sqlite3.sqlite_version))
name = 'name'
db_path = _DB_PATH
conn = _connect(db_path)
c = conn.cursor()
c.execute('''\
DROP TABLE IF EXISTS
test_table
''')
c.execute('''\
CREATE TABLE IF NOT EXISTS
test_table (name text, count integer)
''')
c.execute('''\
CREATE UNIQUE INDEX IF NOT EXISTS
files_index ON test_table (name)
''')
c.execute('''\
INSERT OR REPLACE INTO test_table
(name, count)
VALUES (?, ?)
''', (name, 0))
conn.commit()
conn.close()
logger.debug('Creating a child')
child = Process(target=incrementer_process,
args=(db_path, name))
#child = Thread(target=incrementer_process,
# args=process_args,
# kwargs=process_kwargs)
child.start()
child.join()
logger.info('value: {}'.format(get_count(db_path, name)))
if __name__ == '__main__':
freeze_support()
main()
Erstellen Sie im Hauptprozess eine sqlite3-Datenbank und erhöhen Sie den Wert über multiprocessing.Process
um 1.
Es ist keine Situation, in der Rennbedingungen auftreten.
Es ist ein wenig schlampig, aber es verursacht keine Probleme mit "therading.Thread".
$ pyenv shell 3.5.2-nativesqlite3
$ ./sqlite3_sierra_exp.py
2016-10-24 22:14:29,065 python version: 3.5.2 (default, Oct 24 2016, 22:06:56)
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.38)]
2016-10-24 22:14:29,065 module_version: 2.6.0
2016-10-24 22:14:29,065 sqlite3_version: 3.14.0
2016-10-24 22:14:29,072 Creating a child
2016-10-24 22:14:29,081 value: 0
Obwohl ich Pyenv benutze, habe ich plötzlich unglaubliche Ergebnisse erzielt. Ist es 0? ??
Wenn Sie hier Sierras integrierten Python verwenden ...
$ ./sqlite3_sierra_exp.py
2016-10-24 22:15:05,994 python version: 2.7.10 (default, Jul 30 2016, 18:31:42)
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.34)]
2016-10-24 22:15:05,994 module_version: 2.6.0
2016-10-24 22:15:05,994 sqlite3_version: 3.14.0
2016-10-24 22:15:06,001 Creating a child
2016-10-24 22:15:06,009 value: 0
Hallo! ??
Vergleichen Sie zum Vergleich mit dem Ausführungsergebnis von Debian Jessie
$ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux 8.6 (jessie)
Release: 8.6
Codename: jessie
$ pyenv shell system
$ ./sqlite3_sierra_exp.py
2016-10-24 22:16:21,316 python version: 2.7.9 (default, Jun 29 2016, 13:08:31)
[GCC 4.9.2]
2016-10-24 22:16:21,316 module_version: 2.6.0
2016-10-24 22:16:21,316 sqlite3_version: 3.8.7.1
2016-10-24 22:16:21,352 Creating a child
2016-10-24 22:16:21,368 value: 1
Nun, das stimmt. Es ist 1 ...
Ich werde es auch unter Windows versuchen. Es ist ein Screenshot, weil das Kopieren und Einfügen schwierig ist ...
Es ist 1 ... (seufzt
Zusammenfassend scheint es das Ergebnis des folgenden Fehlers zu sein (genau das Problem von libsqlite3, das mit macOS geliefert wird). Apple-supplied libsqlite3 on OS X is not fork safe; can cause crashes
Warten auf die Korrektur der an das Betriebssystem angeschlossenen Bibliothek. Oder wenn Sie sqlite3 3.15.0 von Homebrew mitbringen und verwenden, verschwindet dieses Symptom. Wenn Sie diesen Teil nicht ändern, kann jede Python-Version von den oben genannten Problemen betroffen sein.
$ brew info sqlite3
sqlite: stable 3.15.0 (bottled) [keg-only]
Command-line interface for SQLite
https://sqlite.org/
/usr/local/Cellar/sqlite/3.9.2 (10 files, 2.8M)
Poured from bottle on 2016-08-03 at 14:21:08
/usr/local/Cellar/sqlite/3.15.0 (11 files, 2.9M)
Poured from bottle on 2016-10-24 at 18:12:13
From: https://github.com/Homebrew/homebrew-core/blob/master/Formula/sqlite.rb
==> Dependencies
Recommended: readline ✔
Optional: icu4c ✔
==> Options
--universal
Build a universal binary
--with-dbstat
Enable the 'dbstat' virtual table
--with-docs
Install HTML documentation
--with-fts
Enable the FTS3 module
--with-fts5
Enable the FTS5 module (experimental)
--with-functions
Enable more math and string functions for SQL queries
--with-icu4c
Enable the ICU module
--with-json1
Enable the JSON1 extension
--with-secure-delete
Defaults secure_delete to on
--with-session
Enable the session extension
--with-unlock-notify
Enable the unlock notification feature
--without-readline
Build without readline support
--without-rtree
Disable the R*Tree index module
==> Caveats
This formula is keg-only, which means it was not symlinked into /usr/local.
macOS provides an older sqlite3.
Generally there are no consequences of this for you. If you build your
own software and it requires this formula, you'll need to add to your
build variables:
LDFLAGS: -L/usr/local/opt/sqlite/lib
CPPFLAGS: -I/usr/local/opt/sqlite/include
PKG_CONFIG_PATH: /usr/local/opt/sqlite/lib/pkgconfig
$ LDFLAGS="-L/usr/local/opt/sqlite/lib" \
CPPFLAGS="-I/usr/local/opt/sqlite/include" \
PKG_CONFIG_PATH="/usr/local/opt/sqlite/lib/pkgconfig" \
pyenv install 3.5.2
(Unterlassung)
$ pyenv shell 3.5.2
$ ./sqlite3_sierra_exp.py
2016-10-24 22:19:30,973 python version: 3.5.2 (default, Oct 24 2016, 21:47:12)
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.38)]
2016-10-24 22:19:30,973 module_version: 2.6.0
2016-10-24 22:19:30,973 sqlite3_version: 3.15.0
2016-10-24 22:19:30,978 Creating a child
2016-10-24 22:19:30,992 value: 1
Der Punkt ist, dass sich der Teil sqlite3_version geändert hat.
In der Python-Umgebung von pyenv wird das Popup-Fenster, das anzeigt, dass es abgestürzt ist, nicht angezeigt. Prozessabstürze auf einer Ebene, die selbst "außer BaseException" nicht abfangen kann, sodass der Absturz selbst nicht bemerkt wird.
ich war müde
Recommended Posts