Ну так много хороших ответов, я хочу добавить еще об этом. Это поможет понять Extending v/s Implementing Thread
.Extends очень тесно связывает два файла класса и может привести к довольно сложному решению кода.
Оба подхода выполняют одну и ту же работу, но были некоторые различия. Наиболее распространенным отличием является
Однако, одна существенная разница между реализацией Runnable и продолжением Thread заключается в том, что by extending Thread, each of your threads has a unique object associated with it, whereas implementing Runnable, many threads can share the same object instance.
Следующий пример помогает вам более четко понять
//Implement Runnable Interface...
class ImplementsRunnable implements Runnable {
private int counter = 0;
public void run() {
counter++;
System.out.println("ImplementsRunnable : Counter : " + counter);
}
}
//Extend Thread class...
class ExtendsThread extends Thread {
private int counter = 0;
public void run() {
counter++;
System.out.println("ExtendsThread : Counter : " + counter);
}
}
//Use above classes here in main to understand the differences more clearly...
public class ThreadVsRunnable {
public static void main(String args[]) throws Exception {
// Multiple threads share the same object.
ImplementsRunnable rc = new ImplementsRunnable();
Thread t1 = new Thread(rc);
t1.start();
Thread.sleep(1000); // Waiting for 1 second before starting next thread
Thread t2 = new Thread(rc);
t2.start();
Thread.sleep(1000); // Waiting for 1 second before starting next thread
Thread t3 = new Thread(rc);
t3.start();
// Creating new instance for every thread access.
ExtendsThread tc1 = new ExtendsThread();
tc1.start();
Thread.sleep(1000); // Waiting for 1 second before starting next thread
ExtendsThread tc2 = new ExtendsThread();
tc2.start();
Thread.sleep(1000); // Waiting for 1 second before starting next thread
ExtendsThread tc3 = new ExtendsThread();
tc3.start();
}
}
Вывод вышеуказанной программы.
ImplementsRunnable : Counter : 1
ImplementsRunnable : Counter : 2
ImplementsRunnable : Counter : 3
ExtendsThread : Counter : 1
ExtendsThread : Counter : 1
ExtendsThread : Counter : 1
В интерфейсе интерфейса Runnable создается только один экземпляр класса, и он был разделен разными потоками. Таким образом, значение счетчика увеличивается для каждого доступа к потоку.
В то время как подход класса Thread, вы должны создать отдельный экземпляр для каждого потока. Следовательно, для каждого экземпляра класса выделяется различная память, и каждый имеет отдельный счетчик, значение остается таким же, что означает, что приращение не произойдет, потому что ни одна из ссылок на объекты не является такой же.
Когда использовать Runnable? Используйте интерфейс Runnable, если вы хотите получить доступ к одному и тому же ресурсу из группы потоков. Избегайте использования класса Thread здесь, потому что создание нескольких объектов потребляет больше памяти, и это становится большой служебной нагрузкой.
Класс, который реализует Runnable, не является нитью и просто классом. Чтобы Runnable стал потоком, вам нужно создать экземпляр Thread и передать себя в качестве цели.
В большинстве случаев интерфейс Runnable должен использоваться, если вы только планируете переопределить run()
и других методов Thread. Это важно, потому что классы не должны подклассифицироваться, если программист не намерен модифицировать или улучшать фундаментальное поведение класса.
Когда необходимо расширить суперкласс, реализация интерфейса Runnable более подходит, чем использование класс Thread. Потому что мы можем расширять другой класс при реализации интерфейса Runnable для создания потока.
Надеюсь, это поможет!
Основная проблема заключается в том, что (в вашей системе) matplotlib по умолчанию использует x-using бэкэнд. У меня была одна и та же проблема на одном из моих серверов. Решение для меня заключалось в том, чтобы добавить следующий код в место, которое читает перед любым другим импортом pylab / matplotlib / pyplot:
import matplotlib
# Force matplotlib to not use any Xwindows backend.
matplotlib.use('Agg')
Альтернативой является установка его в ваш .matplotlibrc
Еще одна вещь, чтобы проверить, разрешен ли ваш текущий пользователь для подключения к X-дисплею. В моем случае root не был допущен к этому, и matplotlib жаловался на ту же ошибку.
user@debian:~$ xauth list
debian/unix:10 MIT-MAGIC-COOKIE-1 ae921efd0026c6fc9d62a8963acdcca0
root@debian:~# xauth add debian/unix:10 MIT-MAGIC-COOKIE-1 ae921efd0026c6fc9d62a8963acdcca0
root@debian:~# xterm
source: http://www.debian-administration.org/articles/494 https://debian-administration.org/article/494/Getting_X11_forwarding_through_ssh_working_after_running_su
Чистый ответ - потратить немного времени на правильную подготовку среды выполнения.
Первым методом, который вы должны подготовить среду исполнения, является использование файла matplotlibrc
, как разумно рекомендованный Крисом К. , установив
backend : Agg
в этом файле. Вы можете даже контролировать - без изменений кода - , как и где ищет matplotlib, и находит файл matplotlibrc
.
Второй метод, который вы должны подготовить для своей среды выполнения, - это используйте переменную среды MPLBACKEND
(и сообщите своим пользователям об использовании):
export MPLBACKEND="agg"
python <program_using_matplotlib.py>
Это удобно, потому что вам даже не нужно предоставлять другой файл на диске, чтобы сделать эту работу. Я использовал этот подход, например, для тестирования в непрерывной интеграции и для работы на удаленных компьютерах, которые не имеют дисплеев.
Жесткое кодирование вашего backplan matplotlib для «Agg» в вашем коде на Python похоже на избиение квадратный колышек в круглое отверстие с большим молотком, когда вместо этого вы могли просто сказать matplotlib, что это должно быть квадратное отверстие.
При входе в сервер для выполнения этого кода используйте это:
ssh -X username@servername
-X
избавится от отображаемого имени без знака переменной DISPLAY
:)
Как дополнение к ответу Рейно.
Постоянный способ решить эту проблему - отредактировать файл .matplotlibrc. Найдите его через
>>> import matplotlib
>>> matplotlib.matplotlib_fname()
# This is the file location in Ubuntu
'/etc/matplotlibrc'
Затем измените бэкэнд в этом файле на backend : Agg
. Вот и все.
$MATPLOTLIBRC
в каталог i>, где вы хотите бросить свой собственный matplotlibrc.
– Kenneth Hoste
29 August 2013 в 19:19
Я получил ошибку при использовании matplotlib через Spark. matplotlib.use('Agg')
не работает для меня. В конце концов, для меня работает следующий код. Подробнее здесь
import matplotlib.pyplot as plt.
plt.switch_backend('agg')
Для Google Learning Engine Engine:
import matplotlib as mpl
mpl.use('Agg')
from matplotlib.backends.backend_pdf import PdfPages
И затем для печати в файл:
#PDF build and save
def multi_page(filename, figs=None, dpi=200):
pp = PdfPages(filename)
if figs is None:
figs = [mpl.pyplot.figure(n) for n in mpl.pyplot.get_fignums()]
for fig in figs:
fig.savefig(pp, format='pdf', bbox_inches='tight', fig_size=(10, 8))
pp.close()
и для создания PDF:
multi_page(report_name)
Я обнаружил, что этот фрагмент хорошо работает при переключении между средами X и no-X.
import os
import matplotlib as mpl
if os.environ.get('DISPLAY','') == '':
print('no display found. Using non-interactive Agg backend')
mpl.use('Agg')
import matplotlib.pyplot as plt
В какой системе вы работаете? Похоже, у вас есть система с X11, но переменная среды DISPLAY была неправильно настроена. Попробуйте выполнить следующую команду, а затем повторно запустить вашу программу:
export DISPLAY=localhost:0
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
Это работает для меня.
Я просто повторю то, что сказал @ Иво Бостицки, которого можно упустить. Поместите эти строки в ОЧЕНЬ старт файла py.
import matplotlib
matplotlib.use('Agg')
Или получится ошибка
*/usr/lib/pymodules/python2.7/matplotlib/__init__.py:923: UserWarning: This call to matplotlib.use() has no effect because the the backend has already been chosen; matplotlib.use() must be called *before* pylab, matplotlib.pyplot,*
Это решит проблему отображения
.use
для указания бэкэнд. – Noufal Ibrahim 17 June 2010 в 12:08backend: agg
в~/.config/matplotlib'/matplotlibrc
(например, см. http: //matplotlib.org/faq/troubleshooting_faq.html#locating-matplotlib-config-dir). См. Также matplotlib.org/users/customizing.html , в котором есть пример файла конфигурации внизу страницы. Найти & quot; agg & quot; на этой странице, и вы увидите нужный вариант конфигурации. – Reinout van Rees 6 July 2015 в 08:48