Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 如何管理TCP客户端读/写重叠问题?_Multithreading_Sockets_Tcp_Thread Safety_Labview - Fatal编程技术网

Multithreading 如何管理TCP客户端读/写重叠问题?

Multithreading 如何管理TCP客户端读/写重叠问题?,multithreading,sockets,tcp,thread-safety,labview,Multithreading,Sockets,Tcp,Thread Safety,Labview,我有一个TCP客户端与LabVIEW GUI通信 我的程序在开始时调用connect(),在结束时调用disconnect()。它将调用passCommand(x)来向LabVIEW GUI读取或写入数据。但是,在某些情况下,我有多个线程可能正在调用passCommand(),返回的数据会以某种方式混淆 例如,在主线程中,我将询问电压,它应该是一个介于300和400之间的数字。在另一个线程中,我将询问温度,它应该是0-100之间的数字。电压将返回为25,而温度将达到250 这是TCP通信和线程的

我有一个TCP客户端与LabVIEW GUI通信

我的程序在开始时调用
connect()
,在结束时调用
disconnect()
。它将调用
passCommand(x)
来向LabVIEW GUI读取或写入数据。但是,在某些情况下,我有多个线程可能正在调用
passCommand()
,返回的数据会以某种方式混淆

例如,在主线程中,我将询问电压,它应该是一个介于300和400之间的数字。在另一个线程中,我将询问温度,它应该是0-100之间的数字。电压将返回为25,而温度将达到250

这是TCP通信和线程的已知问题吗?有没有办法解决这个问题,比如实现一个队列或唯一id之类的

import socket as _socket

# get python major version as integer
from sys import version as pythonVersion
pythonVersionMajor = int(pythonVersion[0])

_serverHost = 'localhost'
_serverPort = 50007
isConnected = 0
_sockobj = None
_error_string = "error:"


def connect():
    'opens a connection to LabVIEW Server'
    global _sockobj, isConnected
    _sockobj = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM)      # create socket
    _sockobj.connect((_serverHost, _serverPort))   # connect to LV
    isConnected = 1


def disconnect():
    'closes the connection to LabVIEW Server'
    global isConnected
    _sockobj.close()                             # close socket
    isConnected = 0


def passCommand(command):
    'passes a command to LabVIEW Server'

    ## We prepend the command length (8 char long) to the message and send it to LV
    # Compute message length and pad with 0 on the left if required
    commandSize=str(len(command)).rjust(8,'0')
    # Prepend msg size to msg
    completeCommand=commandSize+command
    # python 3 requires data to be encoded
    if (pythonVersionMajor >= 3):
        completeCommand = str.encode(completeCommand)
    # Send complete command
    _sockobj.send(completeCommand)
    data = _sockobj.recv(11565536)
    # python 3 requires data to be decoded
    if (pythonVersionMajor >= 3):
        data = bytes.decode(data)
    if data.rfind(_error_string) == 0:
        error = True
        data = data[len(_error_string):] # get data after "error:" string
    else:
        error = False
    execString = "lvdata = " + data
    exec(execString, globals())
    if error:
        raise _LabVIEWError(lvdata)
    else:
        return lvdata


class _Error(Exception):
    """Base class for exceptions in this module."""
    pass


class _LabVIEWError(_Error):
    """Exception raised for errors generated in LabVIEW.

    Attributes:
        code -- LabVIEW Error Code
        source -- location of the error
        message -- explanation of the error
    """

    def __init__(self, error):
        self.code = error[0]
        self.source = error[1]        
        self.message = error[2]

    def __str__(self):
        return "%s" % (self.message,)

这是线程最常见问题之一的示例。您正在从多个线程访问一个资源,而该资源不被认为是线程安全的(如果两个线程同时发送/接收,则一个线程可能会得到错误的响应,甚至两个响应)


理想情况下,您应该使用互斥锁锁定对passCommand的访问,以便一次只能由一个线程使用它,或者每个线程打开一个套接字,或者在单个线程中执行所有套接字操作。

这是线程最常见问题之一的示例。您正在从多个线程访问一个资源,而该资源不被认为是线程安全的(如果两个线程同时发送/接收,则一个线程可能会得到错误的响应,甚至两个响应)


理想情况下,您应该使用互斥锁来锁定对passCommand的访问,以便一次只能由一个线程使用它,或者每个线程打开一个套接字,或者在一个线程中执行所有套接字操作。

添加互斥锁会稍微减慢速度,但它解决了问题。感谢已加载的互斥锁,会稍微减慢速度,但它解决了问题。谢谢