套接字和线程

时间:2015-07-17 09:11:25

标签: python multithreading

我目前正在从我有权访问的api中删除库存数据。我是按照以下步骤进行的:

  1. 逐个遍历符号/股票列表
  2. 创建套接字连接并将相关消息发送到api
  3. 接收数据并将其分成几行直到"!EndMSG!"收到该符号的数据完成时
  4. 将数据(字符串)转换为StringIO,然后将其读入pandas数据帧并最终将数据写入sql
  5. 做下一个符号/股票
  6. 相关代码段:

    import threading
    from queue import Queue
    
    q = Queue()
    my_lock = threading.Lock()
    
    def readlines(sock, recv_buffer=4096, delim='\n'):
        buffer = ''
        while True:
            data = sock.recv(recv_buffer)
            buffer += str(data.decode('latin-1'))
    
        while buffer.find(delim) != -1:
            line, buffer = buffer.split('\n', 1)
            yield line
    
    def get_symbol_data(sym, sock):
        with my_lock:
            data = ''
            message = sym + #relevant api specific commands
            sock.sendall(message.encode())
    
            for line in readlines(sock):
                if "!ENDMSG!" in line:
                    break
                data += line + '\n'
    
            data = io.StringIO(data)
            df = pd.read_csv(data)
            df.to_sql(...)
    
    def threader():
        while True:
            sym_tuple = q.get()
            sym = sym_tuple[0]
            sock = sym_tuple[1]
            get_symbol_data(sym, sock)
            q.task_done()
    
    def main():
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.connect((host, port))
    
        # create 4 threads
        for x in range(4):
            t = threading.Thread(target=threader)
            t.daemon = True
            t.start()
    
        syms = ['MSFT', 'AAPL', 'GS', 'F']
        for sym in syms:
            q.put((sym, sock))
        q.join()
        sock.close()
    

    我想将线程纳入其中,以便我不必一次做一个股票。然而,我不确定的是在哪里/如何实施锁定,以便我不会冒险将不正确的股票数据转换为不正确的变量等

    这是我到目前为止所做的:

    {{1}}

    我尝试整合线程只会挂起。没有错误,没有。它只是挂起。希望有人能指出我正确的方向。

    我甚至不确定我是否在正确的位置使用锁? 顺便说一句,如果我不使用锁,程序仍然会挂起。据推测,即使由于没有使用锁而数据全部混乱,它仍然可以工作吗?

1 个答案:

答案 0 :(得分:1)

这是我的2 * [小单位货币]:

  • 应该做什么锁?现在每个线程必须在接收数据之前等待锁定。这不是非常有效,因为网络操作可能是最有可能从并行化中受益的东西。
  • 在每个线程中创建一个套接字。这样,您不需要同步对套接字的访问,也可能完全摆脱锁。或者,使用套接字池。
  • 我不确定您是如何存储数据的,但在更新pandas数据帧时,您可能需要在编写器之间进行同步。你提到SQL - 希望你的数据库能够为你解决这个问题。另一种选择是让API /套接字读取器将其数据报告给第二类线程(或仅主线程),该线程将数据收集/写入存储。

以上所有假设网络操作是您想要首先进行并行化的原因。注释中提到的人可以为所有符号重用套接字。我不知道您的API是如何工作的,但在我看来,这将需要连续收集所有符号。