LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 10-30-2003, 12:33 PM   #1
bretzeltux
LQ Newbie
 
Registered: Oct 2003
Location: Montreal, Canada
Distribution: Fedora Core 2
Posts: 23

Rep: Reputation: 15
Question pthread and ncurses



Hi there ( sorry if my english is not perfect...).

QUESTION: How to work with pthread and ncurses screen asynchronously...

I am writting a C++ UI lib that is based on NCurses. All the drawing/colors/mouse(gpm) are ok.
But using some of my objects in async multi-threaded mode, I have discovered that ncurses lib "getch()" blocks
calls to the addch.. familly, until input events ( from getch() such as mouse or keyboard or term resize ) occurs. I use blocked getch() in the main thread obviously because I want the main thread to sleep to not use 99% of the CPU).

I do my own window/clipping myself. I use only the stdscr WINDOW.


Notice that I am relatively new to NCurses AND pthread

Since I want to quikcly test my programming steps, here below some peace of code for the situation:
( few copy/paste )
...
<pre> ... oops seems format output doesn't work -- sorry for non indented code beliow :-(
class CTimer public CObject{
...
public:
// Start: creates the thread th_id then run it ...
bool Start(bool oneshot=false, bool destroy_thread=false);
private:
pthread_t th_id;
unsigned int _interval;
friend void* th_enter(void*);
bool _once;
bool _th_destroy;
...
...};

// Implementation (relevant for this subject

namespace ncx {

void* th_enter(void* t)
{
NEvent E; // The event data structure
CTimer* T = (CTimer*)t;
while(!T->_destroy_th){
usleep(T->_interval);
E._sender = T;
E.evID = NTIMER_EVENT;
if(T->bActive){
T->ActivateEvent(&E); // Send the timeout event.
++T->count;
}
T->bActive = !T->_once;
}
pthread_exit((void*) 0l);
}

CTimer::~CTimer()
{
UnRegisterEvent( NTIMER_EVENT );
pthread_cancel(th_id);
}
/*!
\fn ncx::CTimer::Start(bool oneshot=false, bool th_Destroy=false)
*/
bool CTimer::Start(bool oneshot, bool th_Destroy)
{
_once = oneshot;
_destroy_th = th_Destroy;
bActive = true;
pthread_create(&th_id, 0l, th_enter, (void*)this);
}

}; // namespace ncx;

and the application code that propagates the events:
...
void CApplication::ActivateEvent(CObject* _sender, NEvent* E)
{
_evID* id = _evIDNode(E->evID);
_evMap* idc;
CObject* O;
if(! id ) return;
// Validate sender object of the event:
if(( idc = hasSender(id, _sender)) ==0l)
return;
nodelay(stdscr, true);// this is a try to break the blocking state of ncurses::getch(); -- no success
E->_sender = _sender;
// propagate the event to client objects;
evclients_t clist = idc->_Clients;
if( clist.empty() ) return;
for (list<CObject*>::iterator IT = clist.begin(); IT != clist.end(); IT++){
O = *IT;
// Object must return "false" to abort the propagation of this event.
if(O->ProcessEvent(E)) break; // my label::ProcessEvent() get called.
}
nodelay(stdscr,false); // restore the blocking ncurses::getch();
return;
// It does not work async.
}

---------------------------------------
</pre>
So, let say I create a CTimer instance and bind it to a Label-widget object to show the current time on the screen, every 1 000 000 usleep units ( one second ...I think...).

Then a Label::ProcessEvent(my CTimer event) get called from my application event manager and then the label widget updates its drawing area with the time. In Fact it is doing it but ncurses::getch() blocks the screen update ( addch() ) .

I hope my problem is clearly described.
Thanks.

Last edited by bretzeltux; 10-30-2003 at 12:41 PM.
 
Old 10-30-2003, 01:42 PM   #2
LogicG8
Member
 
Registered: Jun 2003
Location: Long Island, NY
Distribution: Gentoo Unstable (what a misnomer)
Posts: 380

Rep: Reputation: 30
I'm not even going to try to wade through the code,
but it sounds as if you need to use the halfdelay()
function.

http://en.tldp.org/HOWTO/NCURSES-Pro...OWTO/init.html
 
Old 10-30-2003, 02:10 PM   #3
bretzeltux
LQ Newbie
 
Registered: Oct 2003
Location: Montreal, Canada
Distribution: Fedora Core 2
Posts: 23

Original Poster
Rep: Reputation: 15
halfdelay() -- half solution to the issue...

Thanks LogicG8 for your suggestion...but as the title says ,
it solves the problem "half" way because this will lower the CPU usage according to the value passed to the halfdelay function. the larger value will be lower cpu rush. But longer sleep value will in turn, lower refresh speed of the screen.

I need to find a solution to be really ASYNC.

BTW, I read ( google search ) that other ncurses and pthread programmers has the same trouble... But no (links to) solutions found :-(

Thanks again ,
Bretzel
 
Old 10-30-2003, 02:26 PM   #4
LogicG8
Member
 
Registered: Jun 2003
Location: Long Island, NY
Distribution: Gentoo Unstable (what a misnomer)
Posts: 380

Rep: Reputation: 30
If that's the case I have another idea you could try using
signals. Use

alarm(1);

and check for EINTR on the other side of the getch call.

if 1 second isn't fine grained enough timing you can use
select() to do the timing for you and raise() the alarm signal
yourself.
 
Old 10-30-2003, 03:07 PM   #5
bretzeltux
LQ Newbie
 
Registered: Oct 2003
Location: Montreal, Canada
Distribution: Fedora Core 2
Posts: 23

Original Poster
Rep: Reputation: 15
alarm(1) ..

hehe thanks again,
I am adapting my code right now to work with the halfdelay solution. I expect it to be the nearest behaviour I need regarding screen refreshes blocking.

I would want to tell you that the "timer" thread does its work very find ( I dump traces of the thread operations into a logfile. then tailing -f the file show the traces at every timeout as expected ). thus the famous ncurses screen refresh can be delayed since it is a lower UI priority :-)

Heheh again thank you again LogicG8 :-)

BTW: ncurses::getch() can be half-blocking also by the call or by stdscr->_delay = x where x >0...
Bretzel
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Pthread JanusPaul Programming 8 02-09-2005 05:46 PM
Pthread in c++ BoldKiller Programming 3 08-30-2004 05:52 AM
about pthread c12ayon Programming 6 10-25-2003 04:37 AM
need help about pthread c12ayon Programming 1 10-24-2003 07:47 AM
ncurses-5.2-28 conflicts with file from package ncurses-5.2-12 tubby Linux - Software 4 06-16-2002 12:00 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 03:41 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration