new default "starting threads" algorithm

This commit is contained in:
Alexis Delhaie
2020-10-02 23:03:47 +02:00
parent f54c15aff8
commit 3509ae6bb1
3 changed files with 106 additions and 32 deletions

View File

@@ -0,0 +1,59 @@
import threading
import time
import queue
import os
import sys
def get_available_threads():
if sys.platform == 'win32':
return (int)(os.environ['NUMBER_OF_PROCESSORS'])
else:
return (int)(os.popen('grep -c cores /proc/cpuinfo').read())
SIZE = get_available_threads()
q = queue.Queue()
not_finished = True
class ProducerThread(threading.Thread):
def __init__(self, threads):
super(ProducerThread,self).__init__()
self.threads = threads
def run(self):
global not_finished
try:
i = 0
while i < len(self.threads):
if q.qsize() < SIZE:
q.put(self.threads[i])
i += 1
while q.qsize() > 0:
time.sleep(1)
except:
pass
not_finished = False
class ConsumerThread(threading.Thread):
def __init__(self):
super(ConsumerThread,self).__init__()
def run(self):
while not_finished:
if q.qsize() > 0:
t = q.get()
t.start()
t.join()
def start(threads):
p = ProducerThread(threads)
p.start()
consumers = []
for _ in range(get_available_threads()):
c = ConsumerThread()
consumers.append(c)
c.start()
p.join()
for c in consumers:
c.join()

View File

@@ -8,9 +8,12 @@ from rich import box
from rich.console import Console from rich.console import Console
from rich.table import Table from rich.table import Table
from thread import StressThread from thread import StressThread
import thread
import basic_producer_consumer
console = Console(highlight=False) console = Console(highlight=False)
VERSION = "1.2" VERSION = "1.3"
thread.console = console
def main(): def main():
if ((len(sys.argv) >= 2) and (("--help" in sys.argv) or ("/?" in sys.argv))): if ((len(sys.argv) >= 2) and (("--help" in sys.argv) or ("/?" in sys.argv))):
@@ -28,33 +31,44 @@ def main():
thread_number = int(get_args("-t", False, 1007, 1008, "5")) thread_number = int(get_args("-t", False, 1007, 1008, "5"))
timeout = int(get_args("-tm", False, 1009, 1010, "10")) timeout = int(get_args("-tm", False, 1009, 1010, "10"))
one_by_one = get_flag("--one-by-one") one_by_one = get_flag("--one-by-one")
ignore_available_threads = get_flag("--ignore-available-threads")
self_signed = get_flag("--allow-self-signed") self_signed = get_flag("--allow-self-signed")
start(host, port, path, timeout, thread_number, allow_ssl, self_signed, one_by_one) if one_by_one and ignore_available_threads:
console.print("[red]Error[/]: ambigous arguments, --one-by-one and --ignore-available-threads cannot be in the same command", style="bold")
return
def start(host, port, path, timeout, thread_number, allow_ssl, self_signed, one_by_one = False): start(host, port, path, timeout, thread_number, allow_ssl, self_signed, one_by_one, ignore_available_threads)
def start(host, port, path, timeout, thread_number, allow_ssl, self_signed, one_by_one = False, ignore_available_threads = False):
thread_array = [] thread_array = []
for i in range(0, thread_number): for i in range(0, thread_number):
thread_array.append(StressThread(host, port, path, timeout, i, allow_ssl, self_signed, VERSION)) thread_array.append(StressThread(host, port, path, timeout, i, allow_ssl, self_signed, VERSION))
for t in thread_array: if one_by_one:
if one_by_one: start_one_by_one(thread_array)
t.run() elif ignore_available_threads:
else: start_all(thread_array)
else:
basic_producer_consumer.start(thread_array)
show_stat(thread_array, (timeout * 1000))
# Run requests in one thread
def start_one_by_one(threads):
for t in threads:
t.run()
# Start all requests in the same time
def start_all(threads):
for t in threads:
started = False
while not started:
try: try:
t.start() t.start()
started = True
except: except:
b = False time.sleep(1)
while not b: for t in threads:
try: t.join()
t.start()
b = True
except:
time.sleep(1)
if not one_by_one:
for t in thread_array:
t.join()
show_stat(thread_array, (timeout * 1000))
def show_stat(tArray, timeoutInMs): def show_stat(tArray, timeoutInMs):
total, succeeded = [0, 0] total, succeeded = [0, 0]
@@ -86,21 +100,22 @@ def show_stat(tArray, timeoutInMs):
def show_help(): def show_help():
console.print("") console.print("")
console.print("Usage: [bold]<executable> -h host -p path [--port port] [-t number_of_thread] [-tm timeout_in_second] [--ssl [--allow-self-signed]][/]") console.print("Usage: [bold]<executable> -h host -p path [--port port] [-t number_of_thread] [-tm timeout_in_second] [--ssl [--allow-self-signed]][/]")
console.print("Exemple: st.exe -h www.google.fr -p / -t 10") console.print("Exemple: st -h www.google.fr -p / -t 10")
console.print(" python main.py -h www.google.fr -p / -t 10") console.print(" py main.py -h www.google.fr -p / -t 10")
console.print("") console.print("")
console.print("Available arguments:") console.print("Available arguments:")
console.print(" -h host The server IP or domain name") console.print(" -h host The server IP or domain name")
console.print(" -p path The path of the HTTP resource") console.print(" -p path The path of the HTTP resource")
console.print(" --port port The server HTTP port") console.print(" --port port The server HTTP port")
console.print(" -t thread Number of threads") console.print(" -t thread Number of threads")
console.print(" -tm second Timeout of the request") console.print(" -tm second Timeout of the request")
console.print(" --one-by-one Send request one by one") console.print(" --one-by-one Send request one by one")
console.print(" --ssl Use HTTPS/SSL") console.print(" --ignore-available-threads Ignore physical number of threads and start all request in the same time")
console.print(" --allow-self-signed Allow self signed SSL certificate") console.print(" --ssl Use HTTPS/SSL")
console.print(" --allow-self-signed Allow self signed SSL certificate")
console.print(" --help") console.print(" --help")
console.print(" /? Show this page") console.print(" /? Show this page")
console.print(" --version Get information about the application and the system") console.print(" --version Get information about the application and the system")
def show_author(): def show_author():
console.print("[bold]Basic HTTP Stress test[/]") console.print("[bold]Basic HTTP Stress test[/]")

View File

@@ -7,7 +7,7 @@ import ssl
import encodings.idna import encodings.idna
from rich.console import Console from rich.console import Console
console = Console(highlight=False) console = None
class StressThread (threading.Thread): class StressThread (threading.Thread):