LINUX.ORG.RU

Почему не работает эта программа?


0

0

Почему эта программа работает только при NUM_THREADS < 8?
Подскажите уважаемые Гуру.

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

<PRE><TT>
#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<pthread.h>
#include<sys/time.h>

#include <X11/Xlib.h>
#include<X11/Xutil.h>
#include <X11/cursorfont.h>
#include <X11/keysym.h>
#include <X11/Xatom.h>
#include <X11/Xcms.h>

#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<count;++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;
}
</TT></PRE>

anonymous

И чему вас в школе чат... Вам не кажется что в иксовых приложения есть отдельные функции для работы с потоками и которые тоже иногда следует использовать?

anonymous
()

Какой у тебя размер свободной памяти на момент запуска и какой размер стековой памяти для треда выставлен в системе. К примеру, размер может быть 8 метров. 8*8 уже 64 метра.

burivuh
()
Ответ на: комментарий от burivuh

Размер свободной памяти больше 2G. Программа вылетает не по Segmentation Fault, а по ошибке Xlib. Поток живет не больше 200 mc. Одновременно на экране не больше 20 окон. Вылет программы тем более вероятен, чем больше окон.

anonymous
()
Ответ на: комментарий от anonymous

> Программа вылетает не по Segmentation Fault, а по ошибке Xlib

когда у тебя хватит ума написать сюда текст ошибки, то может что-то и посоветуют тебе...
про телепатов слышал?

anonymous
()
Ответ на: комментарий от anonymous


Для тех кто в бронепоезде

X Error of failed request: BadWindow (invalid Window parameter)
Major opcode of failed request: 4 (X_DestroyWindow)
Resource id in failed request: 0x5400001
Serial number of failed request: 17
Current serial number in output stream: 19

anonymous
()

В X под словом Display скрывается сокет. Все (почти все) функции XLib в него пишут или из него читают. Что происходит, когда несколько потоков соревнуются за один сокет, наверное, расписывать не надо. Лечение: организовать сериализацию доступа по записи и диспетчеризацию чтения. Проще всего этого добиться, выделив специальный поток для общения с сервером.

vnp
()
Ответ на: комментарий от vnp

О господи. Первым постом же ясно сказали, для тредовых иксовых приложений следует использовать функции-разграничители доступа для тредов XthreadLock & XthreadUnLock - за название не ручаюсь, но смысл понятен. У тебя несколько потоков одновременно пишут в структуру описателя, что недопустимо, поскольку второй тред затирает данные до того как первый успел окончательно отработаь. В итоге "бэд виндоу".

anonymous
()
Ответ на: комментарий от anonymous

Очень интересно читать все это. Хоть бы один посмотрел, что делает программа. В каждом потоке открывается свой собственный Display. Зачем там блокировки? XLockDisplay блокирует свой Display. Можно, конечно, поставить блокировки (пытался ради шутки), только программа ведет себя также как и без блокировок.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.