首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >python: Mac OS X. malloc错误。未分配要释放的指针。中止陷阱6

python: Mac OS X. malloc错误。未分配要释放的指针。中止陷阱6
EN

Stack Overflow用户
提问于 2014-07-14 22:19:58
回答 3查看 5.8K关注 0票数 3

我正在运行一个多线程的python脚本。它所做的就是抓取网页并插入/更新到mysql中。以下是我的代码

mythread.py

代码语言:javascript
复制
import threading
import time

class MyThread (threading.Thread):
    def __init__(self, threadID, threadname, q):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.threadname = threadname
        self.queue = q
        self.__exitFlag = False
        self.__signal_lock = threading.Lock()

    def run(self):
        print "Starting " + self.threadname
        self.process_data()
        print "Exiting " + self.threadname

    def stop(self):
        with self.__signal_lock:
            self.__exitFlag = True

    def process_data(self):
        while not self.__exitFlag:
            if not self.queue.empty():
                data = self.queue.get()
                # crawl data from the web...
                # update to mysql
                # assuming we have already connected mysql:
                # db = MySQLDb()
                # db.connect
                query = ""
                db.query(query)

mysql_db.py

代码语言:javascript
复制
class MySQLDb:
    conn = None

    def connect(self):
        self.conn = MySQLdb.connect(
            host="127.0.0.1",
            user = "root",
            passwd = "password",
            db = "moviestats")

        self.cursor = self.conn.cursor(MySQLdb.cursors.DictCursor)

    def query(self, sql):
        try:
            self.cursor.execute(sql)
            self.conn.commit()
        except (AttributeError, MySQLdb.OperationalError):
            # solution to: MySQL server has gone away
            self.cursor.close()
            self.connect()
            self.cursor = self.conn.cursor(MySQLdb.cursors.DictCursor)
            self.cursor.execute(sql)
            self.conn.commit()

以下是错误日志:

代码语言:javascript
复制
Process:         Python [905]
Path:            /Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python
Identifier:      Python
Version:         2.7.7 (2.7.7)
Code Type:       X86-64 (Native)
Parent Process:  bash [751]
Responsible:     Terminal [410]
User ID:         501

Date/Time:       2014-07-09 22:31:43.221 +0800
OS Version:      Mac OS X 10.9.3 (13D65)
Report Version:  11
....

....
Crashed Thread:  5

Exception Type:  EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000

Application Specific Information:
abort() called
*** error for object 0x100a4b600: pointer being freed was not allocated
......
Thread 5 Crashed:
0   libsystem_kernel.dylib          0x00007fff83153866 __pthread_kill + 10
1   libsystem_pthread.dylib         0x00007fff8de8735c pthread_kill + 92
2   libsystem_c.dylib               0x00007fff8ef88b1a abort + 125
3   libsystem_malloc.dylib          0x00007fff8220707f free + 411
4   libmysqlclient.18.dylib         0x0000000101027302 vio_delete + 44
5   libmysqlclient.18.dylib         0x000000010100709a end_server + 48
6   libmysqlclient.18.dylib         0x0000000101006f81 cli_safe_read + 49
7   libmysqlclient.18.dylib         0x000000010100b469 cli_read_query_result + 26
8   libmysqlclient.18.dylib         0x000000010100a648 mysql_real_query + 83
9   _mysql.so                       0x0000000100533be8 _mysql_ConnectionObject_query + 85
10  org.python.python               0x00000001000c2fad PyEval_EvalFrameEx + 21405
11  org.python.python               0x00000001000c3bfa PyEval_EvalFrameEx + 24554
12  org.python.python               0x00000001000c3bfa PyEval_EvalFrameEx + 24554
13  org.python.python               0x00000001000c4fb3 PyEval_EvalCodeEx + 2115
14  org.python.python               0x00000001000c33f0 PyEval_EvalFrameEx + 22496
15  org.python.python               0x00000001000c3bfa PyEval_EvalFrameEx + 24554
16  org.python.python               0x00000001000c3bfa PyEval_EvalFrameEx + 24554
17  org.python.python               0x00000001000c4fb3 PyEval_EvalCodeEx + 2115
18  org.python.python               0x00000001000c33f0 PyEval_EvalFrameEx + 22496
19  org.python.python               0x00000001000c3bfa PyEval_EvalFrameEx + 24554
20  org.python.python               0x00000001000c3bfa PyEval_EvalFrameEx + 24554
21  org.python.python               0x00000001000c3bfa PyEval_EvalFrameEx + 24554
22  org.python.python               0x00000001000c4fb3 PyEval_EvalCodeEx + 2115
23  org.python.python               0x000000010003eac0 function_call + 176
24  org.python.python               0x000000010000ceb2 PyObject_Call + 98
25  org.python.python               0x000000010001f56d instancemethod_call + 365
26  org.python.python               0x000000010000ceb2 PyObject_Call + 98
27  org.python.python               0x00000001000bc957 PyEval_CallObjectWithKeywords + 87
28  org.python.python               0x0000000100102f27 t_bootstrap + 71
29  libsystem_pthread.dylib         0x00007fff8de86899 _pthread_body + 138
30  libsystem_pthread.dylib         0x00007fff8de8672a _pthread_start + 137
31  libsystem_pthread.dylib         0x00007fff8de8afc9 thread_start + 13

我用50个线程运行脚本。错误的发生是间歇性的,但它是可重复的。我缩小了问题的范围,这是由于对mysql的插入/更新。我读到这可能是由于并发问题,但我如何解决它?

EN

回答 3

Stack Overflow用户

发布于 2014-12-17 02:29:25

我在使用MySQLdb的OSX上遇到了同样的malloc错误。导致我的错误的事情是在线程之间共享MySQLdb连接。使用每个线程的连接为我修复了它。

从documentation http://mysql-python.sourceforge.net/MySQLdb.html

MySQL协议不能同时处理使用同一连接的多个线程。MySQLdb的一些早期版本利用锁定来实现线程安全性2。虽然使用标准游标类(使用mysql_store_result())实现这一点并不是很难,但使用SSCursor (它使用mysql_use_result();对于后者,您必须确保在执行另一个查询之前已经读取了所有行,这就很复杂了。添加事务使其更加复杂,因为事务在游标执行查询时开始,但在连接对象执行COMMIT或ROLLBACK时结束。除了不能在查询执行期间共享连接之外,两个线程根本不能在事务正在进行时共享连接。这使得代码过于复杂,以至于不值得这么做。

这样做的一般结果是:不要在线程之间共享连接。这真的不值得您或我的努力,而且最终可能会损害性能,因为MySQL服务器为每个连接运行一个单独的线程。当然,您可以在池中缓存连接,并将这些连接一次提供给一个线程。如果您让两个线程同时使用一个连接,MySQL客户端库可能会被抛出并终止。你已经被警告过了。

票数 4
EN

Stack Overflow用户

发布于 2014-07-20 13:54:43

我也有同样的问题,但我想了一些方法来避免对数据库的多线程访问。经过进一步的思考,我认为有很多线程和连接是一种糟糕的做法(或者至少这可能是一件棘手的事情)。考虑如何在不涉及数据库的情况下进行批量读取和写入,并在处理过程中执行多线程。

这可能仍然是Python绑定中的一个bug,但我能够通过简化程序访问数据库的方式并在真正需要并行化的地方并行化代码来取得进展。希望这能有所帮助!

票数 2
EN

Stack Overflow用户

发布于 2015-06-24 08:12:41

一般来说,这种误差可能是随机的。我遇到了这个错误,但是再次运行程序后没有收到这个错误。我将我的程序(虽然也很复杂,但与mysql_db无关)运行了5次。我只在第一次和第四次运行时发现了这个错误。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24738717

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档