nixp.ru v3.0

27 мая 2017,
суббота,
09:15:09 MSK

DevOps с компанией «Флант»
df_0903 написал 23 сентября 2005 года в 11:08 (770 просмотров) Ведет себя неопределенно; открыл 6 тем в форуме, оставил 17 комментариев на сайте.

Задавал этот вопрос на LOR. Народ даже не понял о чем речь

Почему эта программа работает только при NUM_THREADS < 8?

Лучше всего запустить и посмотреть. Завершается по ошибке Xlib.

Причем ошибки могут быть разные. Например

X Error of failed request: BadWindow (invalid Window parameter)

Major opcode of failed request: 4 (X_DestroyWindow)

Resource id in failed request: 0×5400001

Serial number of failed request: 17

Current serial number in output stream: 19

Хотя могут быть и другие. Это зависит от количества потоков и порядка вызова

функций.

Неужели Xlib нельзя использовать в многопоточных приложениях таким образом.

P.S. XLockDisplay не помогает

Компилится g++ -pthread -Wall -W -D_REENTRANT c.cpp -o c -L/usr/X11R6/lib -lpthread -lc -lX11

//——————————————-

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define NUM_THREADS 20

inline unsigned long long get_time()

{

struct timeval tv;

gettimeofday(&tv,NULL);

return ((unsigned long long)tv.tv_sec*1000000L+(unsigned long long)tv.tv_usec);

}

void* func(void* =NULL)

{

Display* xdpy=XOpenDisplay(NULL);

int screen =DefaultScreen(xdpy);

Window root=RootWindow(xdpy,screen);

char tmp[256];

sprintf(tmp,"Thread %lu»,pthread_self());

int tlen=strlen(tmp);

XcmsColor Color;

Color.format=XcmsRGBFormat;

Color.spec.RGB.blue=random()*100;

Color.spec.RGB.green=random()*100;

Color.spec.RGB.blue=random()*100;

XcmsAllocColor(xdpy,DefaultColormap(xdpy,screen),&Color,XcmsRGBFormat);

Window win=XCreateSimpleWindow(xdpy,root,100,100,400,100,6,BlackPixel(xdpy,screen),Colo r.pixel);

XSelectInput(xdpy,win,ExposureMask | KeyPressMask );

XMapWindow(xdpy,win);

GC gc=XCreateGC(xdpy,win,0,NULL);//GCForeground|GCFunction,&gcv);

XEvent event;

unsigned long long ti=get_time();

while(1)

{

while(!XPending(xdpy))

{

if((get_time()-ti)>190000)

goto endL;

sched_yield();

}

XNextEvent(xdpy, &event);

if (XFilterEvent(&event, None))

continue;

switch(event.type)

{

case KeyPress:

{

char wbuffer[256];

int wbuffer_len=sizeof(wbuffer);

KeySym keysym=0;

XLookupString(&event.xkey,wbuffer, wbuffer_len, &keysym,NULL);

if (keysym == XK_Escape)

goto endL;

if (keysym == XK_space)

::exit(0);

break;

}

case Expose:

{

if (event.xexpose.count == 0)

XDrawString(xdpy,win,gc,10,40,tmp,tlen);

break;

}

}

if((get_time()-ti)>190000)

break;

}

endL:

XFreeGC(xdpy,gc);

XDestroyWindow(xdpy,win);

XCloseDisplay(xdpy);

return NULL;

}

int main()

{

while(1)

{

int count=NUM_THREADS;

for(int ii=0;ii

{

pthread_attr_t attr;

pthread_attr_t* attrp=&attr;

pthread_t tid=(pthread_t)-1;

if(pthread_attr_init(attrp)==-1)

attrp=NULL;

else

pthread_attr_setdetachstate(attrp,PTHREAD_CREATE_DETACHED);

pthread_create(&tid,&attr,func,NULL);

}

usleep(250000);

}

return 0;

}

//——————————--

rgo

чего тебя удивляет? это сообщение

Xlib: connection to «:0.0» refused by server

Xlib: Maximum number of clients reached

Killed

всё правильно.

Если у тебя она работает иначе… Мне сложно повторить твою ситуацию — у меня другой компьютер, может быть тормознее, а может и быстрее. Так что колись, что тебе не нравится.

df_0903

Если такая ошибка, то все Ok. Обычно у меня такое возникает при NUM_THREADS > 200. А вот если NUM_THREADS == 10, то получаю обычно

X Error of failed request: BadWindow (invalid Window parameter)

Вот это уже непонятно. Может дело в драйвере под X. У меня Nvidia 1.0-7676.

Надо попробовать nv.

rgo

поиграл с параметрами, и понял, что ты имеешь в виду под «работает». И, кажись, понял вопрос.

Самое странное что у меня она работает именно в том виде в каком приведена. Если поставть NUM_THREADS == 8, то она убивается из-за слишком большого количества соединений.

rgo
df_0903
Вот это уже непонятно. Может дело в драйвере под X. У меня Nvidia 1.0-7676.

Надо попробовать nv.

нет. У меня 7667. От системы зависит. Очень. скорость создания потока, скорость создания окна X’ами, куча всяких разных факторов. Вплоть до того, насколько я активно мышкой шевелю.

df_0903

поменял драйвер на nv. Ошибка стала BadDrawable.

Я давно писал такие программы. Пару потоков всегда работают без проблем.

Недавно решил использовать Xft для TrueType шрифтов. Оказалось эта библиотека

вообще не дружит с потоками. Решил написать тест — до шрифтов даже не дошел.

По всем документам должно работать, но увы.

rgo

ты всегда но таком количестве потоков тестируешь? Тогда не удивительно, что ничего не работает. разработчики-то ленивые, и на столь идиотские развлечения явно не рассчитывают ;). А это именно развлечения — зачем иметь сто или ещё больше потоков, и так чтобы все рисовали текст в окошки? Или столь огромное количество окон?

df_0903

Я написал точно такой же тест для консольного вывода. Поставил количество потоков 300. И все хорошо. Программа крутилась больше часа — ошибок нет. Комп не тормозит. Все замечательно. Я конечно могу ошибаться, но когда-то я делал подобный тест не на xorg, а на xfree и без nptl. Насколько я помню, проблем не было.

rgo

ну, что остаётся остановится на оригинальной мысли что x.org — бажная вещь. :) Хотя я ничего окромя 'Xlib: Maximum number of clients reached' добиться не смог.

df_0903

Странно. Может дело в системе. У меня Ubuntu 5.04, ядро 2.6.13 (пробовал и на

2.6.11). Надо попробовать на чем-нибудь еще.

df_0903

Попробовал! На ноутбуке с Ubuntu и родным ядром (2.6.10) программа вылетает только по Xlib: Maximum number of clients reached. Выходит, дело в связке ядра и системных библиотек.

Uncle Theodore

Можно, я встряну?

1. На фига каждому окну свое соединение с X сервером? Открой одно соединение на всех, вставь assert(xdpy), и передавай это соединение параметром в нити. Когда последняя нить выйдет, закрой соединение. Это, кроме того, избавит тебя от goto.

Вообще, detached нити и goto выглядят очень коряво…

2. После XMapWindow, тебе надо дождаться, пока это мяпание произойдет, прежде чем делать что бы то ни было еще.

for(;;)
      {
      XNextEvent(xdpy, &event);
      if (event.type == MapNotify)
        {
          break;
        };
      };

Good Luck,

UT

df_0903

1. Зачем каждому окну соединение? Это просто тест. Ведь в каждом потоке можно сделать много окон с разными задачами. Например, копирование файлов и т.д.

2. Откуда такая информация о XMapWindow?

apple

[root@localhost apple]# g++ -pthread -Wall -W -D_REENTRANT proga.cpp -o c -L/usr/X11R6/lib -lpthread -lc -lX11

proga.cpp:8:24: X11/Xlib.h: No such file or directory

proga.cpp:9:24: X11/Xutil.h: No such file or directory

proga.cpp:10:30: X11/cursorfont.h: No such file or directory

proga.cpp:11:26: X11/keysym.h: No such file or directory

proga.cpp:12:25: X11/Xatom.h: No such file or directory

proga.cpp:13:24: X11/Xcms.h: No such file or directory

proga.cpp: In function `void* func(void*)’:

proga.cpp:26: error: `Display' undeclared (first use this function)

proga.cpp:26: error: (Each undeclared identifier is reported only once for each function it appears in.)

proga.cpp:26: error: `xdpy' undeclared (first use this function)

proga.cpp:26: error: `XOpenDisplay' undeclared (first use this function)

proga.cpp:27: error: `DefaultScreen' undeclared (first use this function)

proga.cpp:28: error: `Window' undeclared (first use this function)

proga.cpp:28: error: expected `;' before «root»

proga.cpp:33: error: `XcmsColor' undeclared (first use this function)

proga.cpp:33: error: expected `;' before «Color»

proga.cpp:34: error: `Color' undeclared (first use this function)

proga.cpp:34: error: `XcmsRGBFormat' undeclared (first use this function)

proga.cpp:38: error: `DefaultColormap' undeclared (first use this function)

proga.cpp:38: error: `XcmsAllocColor' undeclared (first use this function)

proga.cpp:40: error: expected `;' before «win»

proga.cpp:41: error: `win' undeclared (first use this function)

proga.cpp:41: error: `ExposureMask' undeclared (first use this function)

proga.cpp:41: error: `KeyPressMask' undeclared (first use this function)

proga.cpp:41: error: `XSelectInput' undeclared (first use this function)

proga.cpp:42: error: `XMapWindow' undeclared (first use this function)

proga.cpp:43: error: `GC' undeclared (first use this function)

proga.cpp:43: error: expected `;' before «gc»

proga.cpp:45: error: `XEvent' undeclared (first use this function)

proga.cpp:45: error: expected `;' before «event»

proga.cpp:51: error: `XPending' undeclared (first use this function)

proga.cpp:58: error: `event' undeclared (first use this function)

proga.cpp:58: error: `XNextEvent' undeclared (first use this function)

proga.cpp:60: error: `None' undeclared (first use this function)

proga.cpp:60: error: `XFilterEvent' undeclared (first use this function)

proga.cpp:65: error: `KeyPress' undeclared (first use this function)

proga.cpp:69: error: `KeySym' undeclared (first use this function)

proga.cpp:69: error: expected `;' before «keysym»

proga.cpp:70: error: `keysym' undeclared (first use this function)

proga.cpp:70: error: `XLookupString' undeclared (first use this function)

proga.cpp:72: error: `XK_Escape' undeclared (first use this function)

proga.cpp:74: error: `XK_space' undeclared (first use this function)

proga.cpp:78: error: `Expose' undeclared (first use this function)

proga.cpp:81: error: `gc' undeclared (first use this function)

proga.cpp:81: error: `XDrawString' undeclared (first use this function)

proga.cpp:91: error: `XFreeGC' undeclared (first use this function)

proga.cpp:92: error: `XDestroyWindow' undeclared (first use this function)

proga.cpp:93: error: `XCloseDisplay' undeclared (first use this function)

iliya
apple
[root@localhost apple]# g++ -pthread -Wall -W -D_REENTRANT proga.cpp -o c -L/usr/X11R6/lib -lpthread -lc -lX11

proga.cpp:8:24: X11/Xlib.h: No such file or directory

proga.cpp:9:24: X11/Xutil.h: No such file or directory


X includ’ы не установлены или не прописаны в путях поиска include

apple

а другие проги с гуем компилятся

где пути в поисках инклуда?

anonymous

Должен быть путь /usr/include/X11. Это стандартный путь для Xlib библиотек.

Для Debian (Ubuntu) это пакет libx11-dev. Для других — что-то подобное.

rgo

добавь флаг -I/usr/X11R6/include и всё.