When i used the encrypted wallet to test transfer parallelly,i frequently got the trouble: The rpc server is not responding.My test script is like below:
#!/bin/sh
while [ 1 ]
do
./bitcoin-cli listaddressgroupings>null
./bitcoin-cli walletpassphrase "!@#$%^&*" 2
./bitcoin sendtoaddress "mhAW6mzs5DeCbzBUHXBi4U446Fdnr1z8U7" 0.01
done

When i open the dead lock trace macro and check the debug log,i found the last print is as below:
2018-12-17 08:27:58 ThreadRPCServer method=walletpassphrase
2018-12-17 08:27:58 LOCKCONTENTION: cs_main
2018-12-17 08:27:58 Locker: wallet/rpcwallet.cpp:2642
2018-12-17 08:27:58 LOCKCONTENTION: pWallet->cs_wallet
2018-12-17 08:27:58 Locker: wallet/rpcwallet.cpp:2607

The line no 2642 is walletpassphrase and 2607 is LockWallet. I checked the code,i found there is no log printed for this line in function "walletpassphrase":
"LogPrint(BCLog::RPC, "queue run of timer %s in %i seconds (using %s)\n", name, nSeconds, timerInterface->Name());" So i guess the reason may be:
When "walletpassphrase" is running and lock the cs_wallet,the last relock timer triggered and call "LockWallet"."LockWallet" want to lock the cs_wallet but it has been locked by "walletpassphrase",so "LockWallet" is blocked.When "walletpassphrase" run to call "RPCRunLater",the function will erase the timer from the std::map "deadlineTimers",but the timer's timeout call is blocked,so the dead lock take place.
Is my guess right?
How to reslove the issue?
Any help will be appreciative！
if ((int)ret.size() >= (nCount+nFrom)) break;
        }
    }
    
    if (nFrom > (int)ret.size())
        nFrom = ret.size();
    if ((nFrom + nCount) > (int)ret.size())
        nCount = ret.size() - nFrom;
    const std::vector<UniValue>& txs = ret.getValues();
    UniValue result{UniValue::VARR};
    result.push_backV({ txs.rend() - nFrom - nCount, txs.rend() - nFrom }); 
    return result;
}
static UniValue listsinceblock(const JSONRPCRequest& request)
{
    std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
    const CWallet* const pwallet = wallet.get();
    if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
        return NullUniValue;
    }
            RPCHelpMan{"listsinceblock",
                "\nGet all transactions in blocks since block [blockhash], or all transactions if omitted.\n"
                "If \"blockhash\" is no longer a part of the main chain, transactions from the fork point onward are included.\n"
                "Additionally, if include_removed is set, transactions affecting the wallet which were removed are returned in the \"removed\" array.\n",
                {
                    {"blockhash", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, "If set, the block hash to list transactions since, otherwise list all transactions."},
                    {"target_confirmations", RPCArg::Type::NUM,  "1", "Return the nth block hash from the main chain. e.g. 1 would mean the best block hash. Note: this is not used as a filter, but only affects [lastblock] in the return value"},
                    {"include_watchonly", RPCArg::Type::BOOL,  "true for watch-only wallets, otherwise false", "Include transactions to watch-only addresses (see 'importaddress')"},
                    {"include_removed", RPCArg::Type::BOOL,  "true", "Show transactions that were removed due to a reorg in the \"removed\" array\n"
            "                                                           (not guaranteed to work on pruned nodes)"},