What is the difference between timer0_millis and function millis () ?
timer0_millis is a variable, and millis() is a function. They're both defined in the file wiring.c. timer0_millis gets its value in the interrupt service routine (ISR) for Timer0. That ISR is also in wiring.c. millis() returns the value of timer0_millis. wiring.c is in this folder:
where .. is the folder containing the Arduino IDE.
timer0_millis is an unsigned long, and it's four bytes long. The processor has to read four memory locations to fetch its value. When you read timer0_millis directly, there's a chance that a timer interrupt will occur while timer0_millis is being read. That will change the value of timer0_millis, and there's a chance that the result will be garbled. millis() manages the interrupt enable bit in the processor status register to ensure that no interrupts occur while timer0_millis is being read.
You can manage interrupts yourself, by disabling them with noInterrupts() or cli() before reading timer0_millis, and re-enabling them with interrupts() or sei() afterward. But, with the availability of millis(), there doesn't seem to be much of a reason to go to the effort, or take the risk. If you forget to manage interrupts, and misoperations result, the code will be very difficult to troubleshoot.
Another good reason to avoid using timer0_millis is this: once your sketch has access to timer0_millis, it can write a value to it - as your sketch does. That may appear to be convenient, but it's troublesome. It's not so bad in a simple sketch, but, in a more complicated program, several processes may need to fetch the current time independently. If one process modifies the value of the current time, all the others will get inconsistent results. You're dealing that problem right now. Again, if trouble occurs, and you don't have the relevant issue in focus, it will be very hard to troubleshoot. In the long term, I think you'll be happier saving the time when you need to know it, and watching the difference between the current time and the saved value to see how long it's been since a particular event occurred. And, as others in this thread have noted, that will make a second timer unnecessary,
if i declared another variable "timer1_millis" in this manner ... i can have another variable auto-increment indipendent from timer0_millis ?
No. Your sketch doesn't define timer0_millis, or determine how it's managed. That requires a definition of timer0_millis, and an ISR, both found in wiring.c. The "extern" statement only tells your sketch to use the variable timer0_millis as it's defined elsewhere. If you want another "autoincrement" variable based on timer2, you'll have to write that code yourself. It's not clear what benefit you'll get from that, though, because the current time is always available using millis().