[PYTHON] Précautions lors de l'utilisation de sqlite3 de macOS Sierra (10.12) avec le multitraitement

conditions

Addendum (2016-10-25): 10.2.1 a été publié, mais la situation ne semble pas s'améliorer dans ce cas. Postscript (2017-03-31): confirmé en 10.12.4. Il semble que cela ait été corrigé. Tu l'as fait!

Code de vérification

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()

Créez une base de données sqlite3 dans le processus principal et incrémentez la valeur de 1 via multiprocessing.Process. Ce n'est pas une situation où les conditions de course se produisent. C'est un peu bâclé, mais cela ne pose aucun problème avec therading.Thread.

Résultat de l'opération

$ 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

Même si j'utilise pyenv, j'ai soudainement obtenu des résultats incroyables. Est-ce 0? ??

Si vous utilisez le Python intégré de Sierra ici ...

$ ./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
スクリーンショット 2016-10-24 22.15.14.png

Hey! ??

Comparez avec le résultat de l'exécution sur Debian Jessie pour comparaison

$ 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

Eh bien, c'est vrai. C'est 1 ...

Je vais également l'essayer sous Windows. C'est une capture d'écran car il est difficile de copier et coller ...

スクリーンショット 2016-10-24 22.22.36.png

C'est 1 ... (soupire

Cause

Pour conclure, cela semble être le résultat du bug suivant (exactement le problème de libsqlite3 fourni avec macOS). Apple-supplied libsqlite3 on OS X is not fork safe; can cause crashes

Contre-mesures

En attente de la correction de la librairie attachée à l'OS, un. Ou si vous apportez sqlite3 3.15.0 de Homebrew et que vous l'utilisez, ce symptôme lui-même disparaît. Inversement, si vous ne modifiez pas cette partie, toute version de Python peut être prise dans les problèmes ci-dessus.

$ 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
(Omission)
$ 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

Le fait est que la partie sqlite3_version a changé.

prime

Sous l'environnement Python de pyenv, le pop-up indiquant qu'il s'est écrasé n'apparaît pas. Puisque Process plante à un niveau que même ʻexception de BaseException` ne peut pas attraper, le crash lui-même n'est pas remarqué.

j'étais fatigué

Recommended Posts

Précautions lors de l'utilisation de sqlite3 de macOS Sierra (10.12) avec le multitraitement
Précautions lors de l'utilisation de six avec Python 2.5
Précautions lors de l'utilisation de la bibliothèque google-cloud avec GAE / py
Précautions lors de l'utilisation de Chainer
Lors de l'utilisation d'optparse avec iPython
Usurpation d'adresse IP à l'aide de tor sur macOS et vérification avec python
J'ai eu une erreur lorsque j'ai installé tweepy sur macOS Sierra, alors je l'ai résolue.
Lorsqu'une erreur _sqlite3 se produit dans la couverture
Précautions lors de l'utilisation de Pit avec Python
Traitement de PermissionError [Error 1] of pip install -U pip sur macOS Sierra
Précautions lors de l'installation de tensorflow avec anaconda
Premiers pas avec MicroPython (sur macOS)
Précautions lors de l'utilisation de codecs et de pandas
Précautions lors de l'utilisation de la fonction urllib.parse.quote
Notes sur l'utilisation de rstrip avec python.
Précautions lors de l'utilisation de phantomjs de python
Étapes rapides pour créer un environnement d'apprentissage automatique à l'aide de Jupyter Notebook sur macOS Sierra avec anaconda
Lors de l'utilisation de MeCab avec python dans virtualenv
Installez Java2Python sur macOS High Sierra (10.13)
Paramètres lors de l'utilisation de requêtes Python 3 et de Beautiful Soup avec crostini sur Chromebook
Résolution des erreurs lors de l'installation de numba sur macOS
Points à noter lors de la résolution de problèmes DP avec Python
[python, multitraitement] Comportement des exceptions lors de l'utilisation du multitraitement
Précautions lors de l'utilisation de l'instruction for dans les pandas
Développement d'applications à l'aide de SQLite avec Django (PTVS)
Avertissement lors de l'utilisation de TensorFlow sur Mac
Installation de PIL avec Python 3.x sur macOS
Comment installer cx_Oracle sur macOS Sierra
Erreur survenue dans OpenCV3 et sa solution Précautions lors de l'utilisation d'OpenCV3 sur Mac
Lors de l'utilisation de pygame sur Ubuntu 16.04, l'utilisation du processeur est de 100%
Une histoire addictive lors de l'utilisation de tensorflow sur Android
À propos de AVERTISSEMENT lors de l'empaquetage avec pyinstaller en utilisant pyocr
Utilisation de MLflow avec Databricks ① - Suivi expérimental sur notebook -
Installez Python 3.8.6 sur macOS BigSur à l'aide de pyenv
Précautions lors du traitement des structures de contrôle dans Python 2.6
Génération de clé secrète lors de l'utilisation d'EncryptedCookieStorage avec aiohttp_session
Précautions lors de l'utilisation de tf.keras.layers.TimeDistributed pour la couche personnalisée tf.keras
Installez Python 3 sur MacOS Catalina (avec Homebrew uniquement)
J'ai essayé d'utiliser la base de données (sqlite3) avec kivy
[Développement Web avec Python] Précautions lors de l'enregistrement des cookies
[Python] Remarques sur l'accélération des algorithmes génétiques à l'aide du multitraitement
Qu'utilisez-vous lorsque vous testez avec Python?