1

I'm building system which haves a lot of processes running aside and one is - Getting user IP. For that I use Thread and I need to get variable back. The result is always None when outside the function, but in the loop it keeps printing my IP address. As a result my output is:

None

Your ip is : 85.206.**.*

My Code:

IPadress = None
def Get_IP():
    while True:
        try:
            data = urlopen(Ip_Url).read()
            adressas = data.decode('UTF-8')
            global IPadress
            IPadress = adressas
            print("Your ip is : ", IPadress)
        except Exception as erroras:
            print("Can't connect!", erroras)
            time.sleep(5)
            sys.exit()
        time.sleep(5)
Thread(target = Get_IP).start()
print(IPadress)

How can I get the result from thread outside the function?

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
user9745220
  • 213
  • 1
  • 2
  • 13
  • Possible duplicate https://stackoverflow.com/questions/11968689/python-multithreading-wait-till-all-threads-finished – yabhishek Sep 22 '19 at 15:20
  • you print it directy after staring thread so thread had no time to put value in variable. Use `threas.join()` to wait for end of thread (but you thread never end so it makes no sends) or use `sleep()` to wait for first result in variable. – furas Sep 22 '19 at 15:23
  • Did my solution help you? Or i miss understood your question? – moe asal Sep 22 '19 at 15:37
  • Read about [threading - barrier-objects](https://docs.python.org/3/library/threading.html#barrier-objects) – stovfl Sep 22 '19 at 15:37

4 Answers4

1

The print statement print(IPadress) is executed before the web request in the function is completed. That's why the printed result is None. If you wait for some seconds before printing it will hold the IP address value.

You can also use a lock variable to make sure you only read the variable after the request is executed.

David Sidarous
  • 1,202
  • 1
  • 10
  • 25
0

When you launch the threads and want to get results from each of them before proceeding, try to use barriers which is provided by .join method of the Thread library. So, instead of waiting for some constant amount of time, which you may not be sure about sometimes, try to use this method-

thread = Thread(target = Get_IP)
thread.start()
thread.join()
print(IPadress)

and entire solution to your problem could look like-

def Get_IP():
    while True:
        try:
            data = urlopen(Ip_Url).read()
            adresses = data.decode('UTF-8')
            global IPadress
            IPadress = adressas
            print("Your ip is : ", IPadress)
            if IPadress: break
        except Exception as erroras:
            print("Can't connect!", erroras)
            time.sleep(5)
            sys.exit()
        time.sleep(5)

thread = Thread(target = Get_IP)
thread.start()
thread.join()
print(IPadress)
yabhishek
  • 408
  • 4
  • 14
  • `IPadress = None def Get_IP(): while True: try: data = urlopen(Ip_Url).read() adressas = data.decode('UTF-8') global IPadress IPadress = adressas #print("Your ip is : ", IPadress) except Exception as erroras: print("Can't connect!", erroras) time.sleep(5) sys.exit() time.sleep(5) thread = Thread(target = Get_IP) thread.start() thread.join() print(IPadress) time.sleep(3) print(IPadress)` nothing prints – user9745220 Sep 22 '19 at 15:33
  • 1
    Why do you have to keep running the while loop? What condition is going to break out of the loop? If you don't remove while loop and keep the barrier, i.e. `.join` it will never reach the last `print` statement as the loop program either exits or just keep executing in the loop. – yabhishek Sep 22 '19 at 15:42
  • But there's one problem with the if ip adress : break. I need to always keep getting the address, not only one time – user9745220 Sep 22 '19 at 15:55
  • If you want to keep getting the addresses without exiting the loop, you will have to accumulate them in something like `list` or `set` and then at the end when your thread exits, print them in the main thread. Otherwise you will only get the last address in the main thread as the previous ones would be overwritten by the new ones. – yabhishek Sep 22 '19 at 15:59
  • The thing I'm trying to do is - always keep getting the ip adress and if the ip got banned in sql the program should get it when thread is running and exit – user9745220 Sep 22 '19 at 16:03
0

@David Sidarous explained the problem. I will tell you how to face it:

You can add a variable - acting like a flag - called get_ip_executed as a boolean. And it will be set False as default.

get_ip_executed = False
def Get_IP():
    global get_ip_executed
    while True:
        try:
            data = urlopen(Ip_Url).read()
            adressas = data.decode('UTF-8')
            global IPadress
            IPadress = adressas
            print("Your ip is : ", IPadress)
            get_ip_executed = True
        except Exception as erroras:
            print("Can't connect!", erroras)
            time.sleep(5)
            sys.exit()
        time.sleep(5)
Thread(target = Get_IP).start() 
While True:
    if get_ip_executed:
        print(IPadress)
        break 

Furthermore, you can increment get_ip_executed after each execution to keep track of it.

moe asal
  • 750
  • 8
  • 24
  • It prints nothing or it keeps on printing? – moe asal Sep 22 '19 at 15:38
  • the problem with this code would be, while the thread executing `Get_IP` would be sleeping due to `time.sleep(5)` statement, the outer `while` would keep printing the previously obtained IP. – yabhishek Sep 22 '19 at 16:03
  • problem can be because `Get_IP` needs `global get_ip_executed` to assign value to external/global variable. – furas Sep 22 '19 at 17:28
0

Just need to add a simple time.sleep(), to wait for few secs to download the string and now it works well.

  IPadress = None
    def Get_IP():
        while True:
            try:
                Ip_Url = 'https://ipecho.net/plain'
                data = urlopen(Ip_Url).read()
                adressas = data.decode('UTF-8')
                global IPadress
                IPadress = adressas
                #print("Your ip is : ", IPadress)
            except Exception as erroras:
                print("Can't connect!", erroras)
                time.sleep(5)
                sys.exit()
            time.sleep(5)
    Thread(target = Get_IP).start()
    time.sleep(0.5)
    print(IPadress)

    print("Jusu IP:",IPadress)
user9745220
  • 213
  • 1
  • 2
  • 13