Задавал этот вопрос на 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;
}
//——————————--
Последние комментарии
- OlegL, 17 декабря в 15:00 → Перекличка 21
- REDkiy, 8 июня 2023 года в 9:09 → Как «замокать» файл для юниттеста в Python? 2
- fhunter, 29 ноября 2022 года в 2:09 → Проблема с NO_PUBKEY: как получить GPG-ключ и добавить его в базу apt? 6
- Иванн, 9 апреля 2022 года в 8:31 → Ассоциация РАСПО провела первое учредительное собрание 1
- Kiri11.ADV1, 7 марта 2021 года в 12:01 → Логи catalina.out в TomCat 9 в формате JSON 1
чего тебя удивляет? это сообщение
всё правильно.
Если у тебя она работает иначе… Мне сложно повторить твою ситуацию — у меня другой компьютер, может быть тормознее, а может и быстрее. Так что колись, что тебе не нравится.
Если такая ошибка, то все Ok. Обычно у меня такое возникает при NUM_THREADS > 200. А вот если NUM_THREADS == 10, то получаю обычно
Вот это уже непонятно. Может дело в драйвере под X. У меня Nvidia 1.0-7676.
Надо попробовать nv.
поиграл с параметрами, и понял, что ты имеешь в виду под «работает». И, кажись, понял вопрос.
Самое странное что у меня она работает именно в том виде в каком приведена. Если поставть NUM_THREADS == 8, то она убивается из-за слишком большого количества соединений.
нет. У меня 7667. От системы зависит. Очень. скорость создания потока, скорость создания окна X’ами, куча всяких разных факторов. Вплоть до того, насколько я активно мышкой шевелю.
поменял драйвер на nv. Ошибка стала BadDrawable.
Я давно писал такие программы. Пару потоков всегда работают без проблем.
Недавно решил использовать Xft для TrueType шрифтов. Оказалось эта библиотека
вообще не дружит с потоками. Решил написать тест — до шрифтов даже не дошел.
По всем документам должно работать, но увы.
ты всегда но таком количестве потоков тестируешь? Тогда не удивительно, что ничего не работает. разработчики-то ленивые, и на столь идиотские развлечения явно не рассчитывают ;). А это именно развлечения — зачем иметь сто или ещё больше потоков, и так чтобы все рисовали текст в окошки? Или столь огромное количество окон?
Я написал точно такой же тест для консольного вывода. Поставил количество потоков 300. И все хорошо. Программа крутилась больше часа — ошибок нет. Комп не тормозит. Все замечательно. Я конечно могу ошибаться, но когда-то я делал подобный тест не на xorg, а на xfree и без nptl. Насколько я помню, проблем не было.
ну, что остаётся остановится на оригинальной мысли что x.org — бажная вещь. :) Хотя я ничего окромя 'Xlib: Maximum number of clients reached' добиться не смог.
Странно. Может дело в системе. У меня Ubuntu 5.04, ядро 2.6.13 (пробовал и на
2.6.11). Надо попробовать на чем-нибудь еще.
Попробовал! На ноутбуке с Ubuntu и родным ядром (2.6.10) программа вылетает только по Xlib: Maximum number of clients reached. Выходит, дело в связке ядра и системных библиотек.
Можно, я встряну?
1. На фига каждому окну свое соединение с X сервером? Открой одно соединение на всех, вставь assert(xdpy), и передавай это соединение параметром в нити. Когда последняя нить выйдет, закрой соединение. Это, кроме того, избавит тебя от goto.
Вообще, detached нити и goto выглядят очень коряво…
2. После XMapWindow, тебе надо дождаться, пока это мяпание произойдет, прежде чем делать что бы то ни было еще.
Good Luck,
UT
1. Зачем каждому окну соединение? Это просто тест. Ведь в каждом потоке можно сделать много окон с разными задачами. Например, копирование файлов и т.д.
2. Откуда такая информация о XMapWindow?
[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)
X includ’ы не установлены или не прописаны в путях поиска include
а другие проги с гуем компилятся
где пути в поисках инклуда?
Должен быть путь /usr/include/X11. Это стандартный путь для Xlib библиотек.
Для Debian (Ubuntu) это пакет libx11-dev. Для других — что-то подобное.
добавь флаг -I/usr/X11R6/include и всё.