Python多线程变量被覆盖和混淆

时间:2014-08-12 04:17:06

标签: python multithreading flash asynchronous sync

它现在尝试为每个线程建立两个连接,但仍然失败。

我认为我解决了共享访问问题,因为它使用self.x而不是局部变量?

我不确定问题是什么:/,你不碰巧成为一名自由职业者?

#!/usr/bin/python
from xml.etree.ElementTree import fromstring
from socks import socksocket, PROXY_TYPE_SOCKS5
from socket import socket, AF_INET, SOCK_STREAM
from linecache import getline
from threading import Thread, current_thread, Lock, activeCount
from os.path import isfile, getmtime
from urllib import urlopen
from time import time, sleep
from sys import exit
from json import loads
from random import randint, randrange, choice
from urlparse import parse_qs
from pprint import pprint


class myThread (Thread):
    def __init__(self, threadID, name):
        Thread.__init__(self)
        self.threadID = threadID
        self.name = name

    def run(self):
        self.user = parse_qs(getline('./_files/ids.txt', randint(1, idLen)).strip("\n"))
        self.proxy = getline('./_files/proxies.txt', randint(1, proxyLen)).strip("\n").split(":")

        self.user2 = parse_qs(getline('./_files/ids.txt', randint(1, idLen)).strip("\n"))
        self.proxy2 = getline('./_files/proxies.txt', randint(1, proxyLen)).strip("\n").split(":")
        try:
            self.socket = socksocket(AF_INET, SOCK_STREAM)
            self.socket.settimeout(5)
            self.socket.setproxy(PROXY_TYPE_SOCKS5, self.proxy[0], int(self.proxy[1]))

            self.socket2 = socksocket(AF_INET, SOCK_STREAM)
            self.socket2.settimeout(5)
            self.socket2.setproxy(PROXY_TYPE_SOCKS5, self.proxy2[0], int(self.proxy2[1]))

            self.socket.connect((chatConnection[0], int(chatConnection[1])))
            self.socket2.connect((chatConnection[0], int(chatConnection[1])))

            send(self.socket, "<y r=\"%s\" v=\"0\" u=\"%s\" />\0" % (room, self.user["UserId"][0]))
            send(self.socket2, "<y r=\"%s\" v=\"0\" u=\"%s\" />\0" % (room, self.user2["UserId"][0]))

            self.data = read(self.socket)
            self.data2 = read(self.socket2)

            if self.data == "" or not self.data: return
            if self.data2 == "" or not self.data2: return

            self.xml = fromstring(self.data.strip(chr(0))).attrib
            self.xml2 = fromstring(self.data2.strip(chr(0))).attrib

            self.bSock = socket(AF_INET, SOCK_STREAM)
            self.bSock.settimeout(5)

            self.bSock2 = socket(AF_INET, SOCK_STREAM)
            self.bSock2.settimeout(5)

            self.bSock.connect(("127.0.0.1", 1337))

            send(self.bSock, "<bot p=\"%s\" yi=\"%s\" au=\"%s\"  />\0" % (self.xml["p"], self.xml["i"], self.xml["au"]))
            self.data = read(self.bSock)

            send(self.bSock, "<bot p=\"%s\" yi=\"%s\" au=\"%s\"  />\0" % (self.xml2["p"], self.xml2["i"], self.xml2["au"]))
            self.data2 = read(self.bSock)

            self.data = self.data.replace("_lol", "")
            self.l5 = self.data[self.data.find('l5="') + 4:]
            self.l5 = self.l5[:self.l5.find('"')]
            self.ya = self.data[self.data.find('c="') + 3:]
            self.ya = self.ya[:self.ya.find('"')]

            self.data2 = self.data2.replace("_lol", "")
            self.l52 = self.data2[self.data2.find('l5="') + 4:]
            self.l52 = self.l52[:self.l52.find('"')]
            self.ya2 = self.data2[self.data2.find('c="') + 3:]
            self.ya2 = self.ya2[:self.ya2.find('"')]

            print self.ya2 + " : " + self.l52

            self.bSock.close()

            self.yaSock = socksocket(AF_INET, SOCK_STREAM)
            self.yaSock.settimeout(5)
            self.yaSock.setproxy(PROXY_TYPE_SOCKS5, self.proxy[0], int(self.proxy[1]))
            self.yaSock.connect((chatConnection[0], int(chatConnection[1])))

            self.yaSock2 = socksocket(AF_INET, SOCK_STREAM)
            self.yaSock2.settimeout(5)
            self.yaSock2.setproxy(PROXY_TYPE_SOCKS5, self.proxy2[0], int(self.proxy2[1]))
            self.yaSock2.connect((chatConnection[0], int(chatConnection[1])))


            send(self.yaSock, "<ya r=\"%s\" u=\"%s\" c=\"%s\" k=\"%s\" />\0" % (room, self.user["UserId"][0], self.ya, self.xml["k"]))
            print read(self.yaSock)
            self.yaSock.close()

            send(self.yaSock2, "<ya r=\"%s\" u=\"%s\" c=\"%s\" k=\"%s\" />\0" % (room, self.user2["UserId"][0], self.ya2, self.xml2["k"]))
            print read(self.yaSock2)
            self.yaSock2.close()

            self.j2 = "<j2 Y=\"2\" l5=\"" + self.l5 + "\" l4=\"1200\" l3=\"844\" l2=\"0\" cb=\"0\" q=\"1\" y=\"" + self.xml["i"] + "\" k=\"" + self.user["k1"][0] + "\" k3=\"0\" p=\"0\" c=\"" + room + "\" f=\"2\" u=\"" + self.user["UserId"][0] + "\" d0=\"0\" n=\"Zuhnny\" a=\"1\" h=\"xat sux\" v=\"0\" />\0"
            self.j22 = "<j2 Y=\"2\" l5=\"" + self.l52 + "\" l4=\"1200\" l3=\"844\" l2=\"0\" cb=\"0\" q=\"1\" y=\"" + self.xml2["i"] + "\" k=\"" + self.user2["k1"][0] + "\" k3=\"0\" p=\"0\" c=\"" + room + "\" f=\"2\" u=\"" + self.user2["UserId"][0] + "\" d0=\"0\" n=\"Zuhnny\" a=\"1\" h=\"xat sux\" v=\"0\" />\0"

            send(self.socket, self.j2)
            send(self.socket2, self.j22)

            while True:
                print self.socket.recv(6096)
                print self.socket2.recv(6096)
                sleep(1)
                send(self.socket, "<m t=\" F U C K X A T %s\" u=\"%s\" />\0" % (randint(0,5000), self.user["UserId"][0]))
                send(self.socket2, "<m t=\" F U C K X A T %s\" u=\"%s\" />\0" % (randint(0,5000), self.user2["UserId"][0]))
        except IOError, err:  pass
        except Exception, error: pass

def read(socket):
    data = socket.recv(1024)
    return data

def send(socket, data):
    socket.sendall(data)

def getChatConnection(room):
    print '\ntest\n'
    if not isfile('./_files/ips.txt') or time() - getmtime('./_files/ips.txt') > 86400:
        fh = open('./_files/ips.txt', 'w')
        fh.write(urlopen('http://xat.com/web_gear/chat/ip2.htm?' + str(time())).read())
        fh.close()
    try:
        fh = open('./_files/ips.txt', 'r')
        iprules = loads(fh.read())

        Fx = iprules[iprules["order"][0][0]]
        xAddr = Fx[1][randint(0, len(Fx[1]) - 1)].split(':')

        if len(xAddr) == 1: xAddr.append(10000)
        if len(xAddr) == 2: xAddr.append(39)

        xPort = xAddr[1] + randint(0, xAddr[2] - 1)
        return (xAddr[0], 9999 + int(room) if int(room) < 8 else 10007 + (int(room) % 32))
    except Exception, e:
        print e

file = open("./_files/proxies.txt")
proxyLen = len(map(lambda(x): x.split(':'), file))

file2 = open("./_files/ids.txt")
idLen = len(map(lambda(x): x.split('\n'), file2))

threadLock = Lock()
threads = []

room = raw_input("Room ID to raid: ")
chatConnection = getChatConnection(room)

for x in range(1000):
    threads.append(myThread(x, "Thread-" + str(x)).start())

# Wait for all threads to complete
for t in threads:
    t.join()

print "Exiting Main Thread"

2 个答案:

答案 0 :(得分:0)

我猜你的问题。我认为这根本不是竞争条件。我没有仔细阅读您的所有代码,但我没有看到任何全局或其他共享变量被突变。但我确实看到了另一个问题。

你不是在缓慢阅读;你只是希望每个bSock.recv(1024)只收到一条消息。这不是TCP的工作方式;您可能会收到一半的消息,或两条消息,或前一条消息的后半部分和下一条消息的前半部分。

如果您没有非常努力地压缩您的计算机或网络,并且您的消息都非常小,它可能(取决于平台)99.9%的时间工作,这意味着您没有注意到任何问题。但是只要你强调一切,它就会更频繁地失败。

你有400个线程,并且从你的旧式代码(例如,except Type, value)看起来你可能在一个足够老的系统上它被卡在Python 2.5上,这意味着你可能是非常努力地强调系统。

你需要通过循环接收来解决此问题,直到你有一个或多个完整的消息,然后处理这些消息,然后返回到循环,而不是处理每个recv,就好像它确保完全一样一条完整的信息。

幸运的是,你正在处理IRC,它(假设你没有做任何DCC等)每行只有一个命令,并且Python有一个很好的套接字包装器,使它们看起来像行缓冲文件。所以你可以这样做:

bfile = bsock.makefile()
for line in bfile:

现在您知道line保证是一个完整的行,即使它必须进行三次读取,并缓冲大部分第三次读取,直到您下次循环。

你在至少三个地方做同样的事情,所以很明显你需要修复它们。此外,您需要确保close套接字和文件正确。而且你需要检测对方何时关闭套接字。 (recv或下一个line将返回一个空字符串。)

答案 1 :(得分:0)

另一种可能性:

所有线程至少有一个共享:bsock套接字。他们都在发布后5秒钟完成了这项工作:

bSock.sendall("<bot p=\"%s\" au=\"%s\" yi=\"%s\" />\0" % (xml["p"], xml["au"], xml["i"]))
data = bSock.recv(1024)

什么阻止线程#42执行其sendall,然后线程#23执行其sendall,然后线程#42执行其recv并获取用于线程的数据# 42?

这就是所谓的“关键部分”或“原子块”:一块代码,一次只能运行一个线程,或者每个人都会感到困惑。通常的方法是共享Lock,并让每个线程在运行此代码之前获取Lock。如果线程#42已经有锁,并且线程#23试图获取它,它将被阻塞,直到线程#42释放锁定,因此它们不可能发生冲突。所以:

bSockLock = threading.Lock()

# ...

for x in range(400):
    Thread(target = __init__, args=[chatConnection, bSock, bSockLock]).start()

# ...

def __init__(chatConnection, bSock):
    # ...
    for x in range(3):
        start(chatConnection, proxies[x][0], proxies[x][1], [ids[x]["UserId"][0], ids[x]["k1"][0], ids[x]["k2"][0]], room, bSock, bSockLock)

# ...

def start(chatConnection, proxyIP, proxyPort, user, room, bSock, bSockLock):
    # ...
    with bSockLock:
        bSock.sendall("<bot p=\"%s\" au=\"%s\" yi=\"%s\" />\0" % (xml["p"], xml["au"], xml["i"]))
        data = bSock.recv(1024)