QProcess啟動(dòng)線程的內(nèi)存問(wèn)題
在使用QProcess的過(guò)程中咽瓷,采用了
start(const QString &program, const QStringList &arguments, OpenMode mode = ReadWrite)
啟動(dòng)與項(xiàng)目相關(guān)的exe文件般哼,然后在采用QIODevice 中 write(const char *data)
進(jìn)行寫(xiě)入厨姚,本來(lái)發(fā)現(xiàn)挺好的炒考,但是突然出現(xiàn)了一個(gè)bug鬓照,在進(jìn)行打開(kāi)QProcess后全跨,居然視頻的流沒(méi)有辦法正常的關(guān)閉藕赞,于是猜測(cè)有QProcess啟動(dòng)另一個(gè)子線程采用了同一個(gè)空間成肘。而采用
static bool startDetached(const QString &program, const QStringList &arguments);
構(gòu)建了兩個(gè)沒(méi)有子父關(guān)系的進(jìn)程時(shí),QProcess中的各種函數(shù)都不起作用斧蜕,例如判斷是否當(dāng)前狀態(tài)的函數(shù)state()
或者寫(xiě)入進(jìn)程函數(shù)write(char*data)
双霍。
查看QT的源代碼后,在qprocess_win.cpp 找到了源代碼startProcess ()
函數(shù)中
struct CreateProcessArguments
{
const wchar_t *applicationName;
wchar_t *arguments;
Q_SECURITY_ATTRIBUTES *processAttributes;
Q_SECURITY_ATTRIBUTES *threadAttributes;
bool inheritHandles;
unsigned long flags;
void *environment;
const wchar_t *currentDirectory;
Q_STARTUPINFO *startupInfo;
Q_PID processInformation;
};
QProcess::CreateProcessArguments cpargs = {
0, (wchar_t*)args.utf16(),
0, 0, TRUE, dwCreationFlags,
environment.isEmpty() ? 0 : envlist.data(),
nativeWorkingDirectory.isEmpty() ? Q_NULLPTR : (wchar_t*)nativeWorkingDirectory.utf16(),
&startupInfo, pid
};
if (modifyCreateProcessArgs)
modifyCreateProcessArgs(&cpargs);
success = CreateProcess(cpargs.applicationName, cpargs.arguments, cpargs.processAttributes,
cpargs.threadAttributes, cpargs.inheritHandles, cpargs.flags,
cpargs.environment, cpargs.currentDirectory, cpargs.startupInfo,
cpargs.processInformation);
而windows CreateProcess的參數(shù)命令
值:CREATE_SEPARATE_WOW_VDM
如果被設(shè)置,新進(jìn)程將會(huì)在一個(gè)私有的虛擬DOS機(jī)(VDM)中運(yùn)行洒闸。另外染坯,默認(rèn)情況下所有的16位Windows應(yīng)用程序都會(huì)在同一個(gè)共享的VDM中以線程的方式運(yùn)行。單獨(dú)運(yùn)行一個(gè)16位程序的優(yōu)點(diǎn)是一個(gè)應(yīng)用程序的崩潰只會(huì)結(jié)束這一個(gè)VDM的運(yùn)行丘逸;其他那些在不同VDM中運(yùn)行的程序會(huì)繼續(xù)正常的運(yùn)行单鹿。同樣的,在不同VDM中運(yùn)行的16位Windows應(yīng)用程序擁有不同的輸入隊(duì)列深纲,這意味著如果一個(gè)程序暫時(shí)失去響應(yīng)仲锄,在獨(dú)立的VDM中的應(yīng)用程序能夠繼續(xù)獲得輸入。所以可以看到為0囤萤,所以以線程的方式運(yùn)行昼窗,公用同一段空間。
解決方式
既然涛舍,不行澄惊,然后采用startDetached
的方式啟動(dòng),然后使用socket的方式兩者進(jìn)行通信富雅。而對(duì)于qt而言掸驱,在文檔中On Windows this is a named pipe and on Unix this is a local domain socket.表明采用了管道的方式,所以不會(huì)造成資源的浪費(fèi)没佑。而QLocalSocket采用的是全雙工的模式毕贼,可以相互之間通信~~