Multithreading in X - Xwindows

This is a discussion on Multithreading in X - Xwindows ; Hi Does anyone has a simple example of multithreading in an X-application ? I want my program to respond to mouse-keyboard events while it is busy doing some other things but don't know how it is done in X. Thanks ...

+ Reply to Thread
Results 1 to 4 of 4

Thread: Multithreading in X

  1. Multithreading in X



    Hi

    Does anyone has a simple example of multithreading in
    an X-application ? I want my program to respond to
    mouse-keyboard events while it is busy doing some
    other things but don't know how it is done in X.

    Thanks in advance

    Kamran


  2. Re: Multithreading in X

    In article <3FCC6BCD.2070403@uio.no>, kamran@uio.no wrote:
    > Hi
    >
    > Does anyone has a simple example of multithreading in
    > an X-application ? I want my program to respond to
    > mouse-keyboard events while it is busy doing some
    > other things but don't know how it is done in X.


    The simplest advice is not to use multi-threading in the interface
    itself. Simply dispatch work from the interface to another thread and
    keep the main thread free for interaction with the user. The only
    trouble is how to feed back the results. The best solution I've got
    sofar is to create a pipe and add that to the X11 inputs. If the
    background thread has a result it either writes the result or a
    handle to the result onto the pipe. The main thread in return
    does the presentation of the results.

    Cheers -- Jan

  3. Re: Multithreading in X

    In article <3FCC6BCD.2070403@uio.no>, wrote:
    >
    >
    >Hi
    >
    >Does anyone has a simple example of multithreading in
    >an X-application ? I want my program to respond to
    >mouse-keyboard events while it is busy doing some
    >other things but don't know how it is done in X.
    >
    >Thanks in advance
    >
    >Kamran
    >


    #include
    #include
    #include
    #include
    #include
    #include

    // queue element for work to be run in its own thread
    typedef struct srb_t {
    struct srb_t * next;
    void (*function)(XtAppContext ac, void *);
    void * data;
    } srb_t;

    static pthread_mutex_t mutex; // lock srb queue
    static pthread_cond_t cond; // idle threads wait here
    srb_t * srb_head;
    srb_t * srb_tail;
    Boolean xt_thread;
    Boolean quit;

    // schedule a unit of work to run in its own thread
    void
    postsrb(void (*function)(XtAppContext ac, void *), void * data)
    {
    srb_t * srb = XtNew(srb_t);

    srb->next = 0, srb->function = function, srb->data = data;
    pthread_mutex_lock(&mutex);
    srb_tail ? srb_tail->next : srb_head = srb;
    srb_tail = srb;
    pthread_cond_signal(&cond), pthread_mutex_unlock(&mutex);
    }

    // typical unit of work -- replace with something useful!
    // Xt calls get app lock, so are safe; however, you must get the
    // app lock yourself if a sequence of calls must be coordinated.
    // X calls are safe, but similarly may require coordination.
    // User data, etc, likely will require mutex protection.
    static void
    workproc(XtAppContext ac, void * data)
    {
    fprintf(stderr, "workproc %ld\n", pthread_self());
    sleep(5);
    fprintf(stderr, "workends %ld\n", pthread_self());
    }

    // sample source of work units -- replace with something useful!
    // called by Xt on keypress events in main window:
    // w - queue a unit of work
    // x - terminate application synchronously
    // c - terminate application asynchronously
    static void
    input(Widget w, XEvent * e, String * s, Cardinal * n)
    {
    XtAppContext ac = XtWidgetToApplicationContext(w);

    switch (XLookupKeysym((XKeyEvent *)e, 0)) {
    case XK_w: postsrb(workproc, 0); break;
    case XK_x: quit = True; break;
    case XK_c: exit(0); break;
    }
    }

    static XtActionsRec actions[] = {{ "Input", input }};

    static char * resources[] = {
    "?.translations: : Input()",
    "?.input: True",
    "?.width: 200", "?.height: 200",
    NULL
    };

    // thread dispatch function.
    // all threads are treated identically; none is specifically reserved for Xt
    static void *
    mainloop(void * data)
    {
    XtAppContext ac = data;
    XEvent event;
    srb_t * srb;

    pthread_mutex_lock(&mutex);
    while (!quit) {
    if ((srb = srb_head)) { // post work unit
    if (!(srb_head = srb->next)) srb_tail = 0;
    pthread_mutex_unlock(&mutex);
    (srb->function)(ac, srb->data), XtFree((char *)srb);
    pthread_mutex_lock(&mutex);
    continue;
    }
    if (!xt_thread) { // post X event via Xt
    xt_thread = True;
    pthread_mutex_unlock(&mutex);
    XtAppNextEvent(ac, &event), XtDispatchEvent(&event);
    pthread_mutex_lock(&mutex);
    xt_thread = False;
    continue;
    }
    pthread_cond_wait(&cond, &mutex); // no work for thread
    }
    pthread_cond_broadcast(&cond), pthread_mutex_unlock(&mutex);
    fprintf(stderr, "exits %ld\n", pthread_self());
    pthread_exit(0);
    }

    int
    main(int argc, char * argv[])
    {
    XtAppContext ac;
    Display * dpy;
    Widget toplevel;
    pthread_attr_t attr;
    pthread_t id;
    int i;

    if (!XInitThreads() || !XtToolkitThreadInitialize()) exit(1);
    XtToolkitInitialize();
    ac = XtCreateApplicationContext();
    XtAppAddActions(ac, actions, XtNumber(actions));
    XtAppSetFallbackResources(ac, resources);
    dpy = XtOpenDisplay(ac, NULL, NULL, "Test", NULL, 0, &argc, argv);
    toplevel = XtVaAppCreateShell(NULL, "Test",
    applicationShellWidgetClass, dpy, NULL);

    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond, NULL);

    XtRealizeWidget(toplevel);

    // NO Xt CALLS PAST THIS POINT !!!

    /*
    for (i = 0; i < 2; i++) // build thread pool
    */
    pthread_create(&id, &attr, mainloop, ac);

    mainloop(ac);
    /*NOTREACHED*/
    return 0;
    }


    CCOPTIONS = -g
    SYS_LIBRARIES = -lXt -lX11 -lpthread
    AllTarget(thread)
    NormalProgramTarget(thread, thread.o,,,)


  4. Re: Multithreading in X



    Many thanks.

    I now have an idea how it works.

    Thanks again

    Kamran



    Kip Rugger wrote:
    > In article <3FCC6BCD.2070403@uio.no>, wrote:
    >
    >>
    >>Hi
    >>
    >>Does anyone has a simple example of multithreading in
    >>an X-application ? I want my program to respond to
    >>mouse-keyboard events while it is busy doing some
    >>other things but don't know how it is done in X.
    >>
    >>Thanks in advance
    >>
    >>Kamran
    >>

    >
    >
    > #include
    > #include
    > #include
    > #include
    > #include
    > #include
    >
    > // queue element for work to be run in its own thread
    > typedef struct srb_t {
    > struct srb_t * next;
    > void (*function)(XtAppContext ac, void *);
    > void * data;
    > } srb_t;
    >
    > static pthread_mutex_t mutex; // lock srb queue
    > static pthread_cond_t cond; // idle threads wait here
    > srb_t * srb_head;
    > srb_t * srb_tail;
    > Boolean xt_thread;
    > Boolean quit;
    >
    > // schedule a unit of work to run in its own thread
    > void
    > postsrb(void (*function)(XtAppContext ac, void *), void * data)
    > {
    > srb_t * srb = XtNew(srb_t);
    >
    > srb->next = 0, srb->function = function, srb->data = data;
    > pthread_mutex_lock(&mutex);
    > srb_tail ? srb_tail->next : srb_head = srb;
    > srb_tail = srb;
    > pthread_cond_signal(&cond), pthread_mutex_unlock(&mutex);
    > }
    >
    > // typical unit of work -- replace with something useful!
    > // Xt calls get app lock, so are safe; however, you must get the
    > // app lock yourself if a sequence of calls must be coordinated.
    > // X calls are safe, but similarly may require coordination.
    > // User data, etc, likely will require mutex protection.
    > static void
    > workproc(XtAppContext ac, void * data)
    > {
    > fprintf(stderr, "workproc %ld\n", pthread_self());
    > sleep(5);
    > fprintf(stderr, "workends %ld\n", pthread_self());
    > }
    >
    > // sample source of work units -- replace with something useful!
    > // called by Xt on keypress events in main window:
    > // w - queue a unit of work
    > // x - terminate application synchronously
    > // c - terminate application asynchronously
    > static void
    > input(Widget w, XEvent * e, String * s, Cardinal * n)
    > {
    > XtAppContext ac = XtWidgetToApplicationContext(w);
    >
    > switch (XLookupKeysym((XKeyEvent *)e, 0)) {
    > case XK_w: postsrb(workproc, 0); break;
    > case XK_x: quit = True; break;
    > case XK_c: exit(0); break;
    > }
    > }
    >
    > static XtActionsRec actions[] = {{ "Input", input }};
    >
    > static char * resources[] = {
    > "?.translations: : Input()",
    > "?.input: True",
    > "?.width: 200", "?.height: 200",
    > NULL
    > };
    >
    > // thread dispatch function.
    > // all threads are treated identically; none is specifically reserved for Xt
    > static void *
    > mainloop(void * data)
    > {
    > XtAppContext ac = data;
    > XEvent event;
    > srb_t * srb;
    >
    > pthread_mutex_lock(&mutex);
    > while (!quit) {
    > if ((srb = srb_head)) { // post work unit
    > if (!(srb_head = srb->next)) srb_tail = 0;
    > pthread_mutex_unlock(&mutex);
    > (srb->function)(ac, srb->data), XtFree((char *)srb);
    > pthread_mutex_lock(&mutex);
    > continue;
    > }
    > if (!xt_thread) { // post X event via Xt
    > xt_thread = True;
    > pthread_mutex_unlock(&mutex);
    > XtAppNextEvent(ac, &event), XtDispatchEvent(&event);
    > pthread_mutex_lock(&mutex);
    > xt_thread = False;
    > continue;
    > }
    > pthread_cond_wait(&cond, &mutex); // no work for thread
    > }
    > pthread_cond_broadcast(&cond), pthread_mutex_unlock(&mutex);
    > fprintf(stderr, "exits %ld\n", pthread_self());
    > pthread_exit(0);
    > }
    >
    > int
    > main(int argc, char * argv[])
    > {
    > XtAppContext ac;
    > Display * dpy;
    > Widget toplevel;
    > pthread_attr_t attr;
    > pthread_t id;
    > int i;
    >
    > if (!XInitThreads() || !XtToolkitThreadInitialize()) exit(1);
    > XtToolkitInitialize();
    > ac = XtCreateApplicationContext();
    > XtAppAddActions(ac, actions, XtNumber(actions));
    > XtAppSetFallbackResources(ac, resources);
    > dpy = XtOpenDisplay(ac, NULL, NULL, "Test", NULL, 0, &argc, argv);
    > toplevel = XtVaAppCreateShell(NULL, "Test",
    > applicationShellWidgetClass, dpy, NULL);
    >
    > pthread_attr_init(&attr);
    > pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    > pthread_mutex_init(&mutex, NULL);
    > pthread_cond_init(&cond, NULL);
    >
    > XtRealizeWidget(toplevel);
    >
    > // NO Xt CALLS PAST THIS POINT !!!
    >
    > /*
    > for (i = 0; i < 2; i++) // build thread pool
    > */
    > pthread_create(&id, &attr, mainloop, ac);
    >
    > mainloop(ac);
    > /*NOTREACHED*/
    > return 0;
    > }
    >
    >
    > CCOPTIONS = -g
    > SYS_LIBRARIES = -lXt -lX11 -lpthread
    > AllTarget(thread)
    > NormalProgramTarget(thread, thread.o,,,)
    >



+ Reply to Thread