When I press "button", a new thread is executed, and dialog is created, but when it reaches gtk_dialog_run, the program quit.

why??this is the output:

Code:

[xcb] Unknown sequence number while processing queue[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called[xcb] Aborting, sorry about that.test: ../../src/xcb_io.c:273: poll_for_event: Assertion `!xcb_xlib_threads_sequence_lost' failed.

I have tried to add "g_thread_init(NULL);" and " gdk_threads_init();" before gtk_init, but with the same result.

From what I recall you're supposed to wrap all GTK calls in a thread with gdk_threads_enter and gdk_threads_leave.

However, my experience is that trying to do anything with GTK in a thread is a bit dodgy. I used to update widgets in a thread by setting the value of an adjustment that was attached to a spin control but ever since the upgrade to GTK3 it has caused segmentation faults.

By the looks of it your code isn't doing anything that requires a thread, any reason for it?

This is a summary of a much larger code. I only wanted to post the problem, not the entire code.

I am developing a network application. So a server must be listening using “accept” call, which blocks, so that's why I need another thread. The main thread for the main application, other thread listening on clients to “connect”. When a connection from a client arrives, a dialog is shown, using gtk_dialog_run (GTK_DIALOG (dialog));

So my problem now is that if I use a server thread, it is always running, will never call to gdk_threads_leave. This is a pseudo code example

Code:

gdk_threads_enter();

while(1){ accept_connections_from_client}gdk_threads_leave(); will never be executed

So right now the only solution is to wrap gtk_dialog_run (GTK_DIALOG (dialog)); with these calls.

- You have created a multi-thread application that only is allowed to use one thread at a time due to locking. And you must use locking because GTK+/GDK and X11 are not thread safe.

- The use of gdk_threads_enter() and gdk_threads_leave() is expected to be deprecated soon in the GTK+ 3 series and removed in GTK+ 4. So try not to depend on it, mainly for the previous reason and also it can make your code slower and harder to read/keep bug free.

- If you must use threads keep all code that deals with the GUI in one thread and have other threads do background work. When the background threads need to they can then communicate their data in a thread safe manner to the GUI thread. Use locks for all shared data, but the use of locks should be kept to a minimum as they then block the running of a thread.

- You are using some features that have been deprecated for a long time now. If you tell us which version of GTK+ you are using then better a answers can be given.

From what little information that you have given you may not require the use of threads. As a note you can monitor files, pipes and sockets using the "GTK main loop" see the man page at http://developer.gnome.org/glib/stable/glib-IO-Channels.html. This then allows you to connect call back functions to the signals and react in a non-blocking way. Without the need for you to explicitly use threads.

I see what you mean, you mean that using theses calls:pthread_mutex_lock(mutex);pthread_mutex_unlock(mutex);

it would be much better.

I have seen the link you post about glib, and seems I have to study it very careful, but it does not have a tutorial. I am following the GTK+ tutorial on internet, but the link you have post is ok. The subjects related with glib threads are very helpful and easy, but the ones related with sockets.......

There are sometime like 13 versions of the GTK+ version 2 series, if you exclude the bug fix versions and development ones.

Use

Code:

pkg-config --modversion gtk+-2.0

on a command line to find out the exact version.

You are confusing POSIX threads with Linux threads. They are not the same and work in very different ways. If your system is very old and you have a choice prefer to use POSIX threads.

No there is not a wrapper to pthread_cancel() in the GLib library so you will need to use POSIX threads if you need this feature. Note that you will need to add extra checks in your code to make sure that proper clean up is done otherwise you may end up with memory leaks and other bugs.

Note in the future you will only be able to call GTK+ from one thread, and no way around that. Not even the use of pthread_mutex_lock(mutex);pthread_mutex_unlock(mutex);will help.

Take another read of the link to the file monitoring documentation. It is very simple and I think you could hook up a call back function to your socket using just two function calls.

I have a few rules about threads.1 Avoid2 Only use it if they are doing processing that would take more than about 0.1 seconds.3 Avoid blocking IO. For example the thread will go to sleep waiting for IO on a socket. This can be converted from blocking to non-blocking and the use of a thread can then be avoided.

Note within the GTK+ main loop it uses the system call select() which is a powerful call. It can wait on several IO channels and perform time-outs all within the one call. If you use this built in power then you can avoid the resource wast-full addition of threads, when all it is doing is waiting for a bit of IO on a socket. Only use threads when you have a user interface to be kept responsive and have some processor intensive task to do at the same time. And if you do use threads make sure everything is done in a thread safe way.

To avoid a blocking accept, you should look into using select or epoll. Both of those will allow you to make your listening socket descriptor non-blocking and then just sit and wait for events to happen on it. Doing so will allow you to use gtk callbacks to generate the dialog, which is from my experience easier and safer. If you need to update some widget I agree with errol that you want to avoid doing so in a thread, what I try to do is use a mutex in a thread to lock the data while it's being updated, and then use that same data from a timer callback that gets launched along with the dialog/window that contains the widget to update.

Hi geoffjay!! thank you very much! I understand what you mean but I have a few questions.

geoffjay wrote:

To avoid a blocking accept, you should look into using select or epoll. Both of those will allow you to make your listening socket descriptor non-blocking and then just sit and wait for events to happen on it.

I have been reading about select and Non-blocking I/O. As you say, select is a blocking call, so if I use select, I will be blocked and need to use a thread. Reading more about I/O, another solution would be Signal driven I/O, but they have recommended me that signals can get lost, signal handlers operate in strange context and shouldn't do very much.....

geoffjay wrote:

If you need to update some widget I agree with errol that you want to avoid doing so in a thread, what I try to do is use a mutex in a thread to lock the data while it's being updated, and then use that same data from a timer callback that gets launched along with the dialog/window that contains the widget to update

I have not understood you very well. What do you mean with a timer callback??

I know that you all would have expressed very clear yourself, it is my fault for so stupid questions.

Being as you're developing a GTK application you should have already launched gtk_main which means you must have a separate thread to read data off of your socket anyhow no? As for using signals to perform I/O, I wouldn't do that personally, especially not when very good facilities like select/epoll/poll/kevent exist.

Here's how I would lay it out (very roughly):

Code:

main setup data create a timeout that checks for new clients and launches dialogs as needed launch pthread/gthread for managing client communication launch gtk main loop

thread setup listening socket add socket to fd set make socket non blocking loop while thread is enabled execute select call (with or without timeout, that's up to you) if listening fd is set create new client data and add it to a "pending clients" queue else if client fd is set read new data from socket else continue

client timeout callback loop while "pending clients" queue is > 0 run a new dialog for the client

This may not be the best way to do it as there is an inherent delay while you're waiting for the next timeout, I'm pretty sure that you can attach a callback to a GQueue as an alternative to a timeout but I didn't feel like looking into how to do that.

Hi geoffay!! thanks a lot! I understood what you meant, the use of g_timeout_add (time, call_back) but in the context of the main thread, so I can update the widget from the main thread.

But now I have other problem again with the gtk_dialog_run, because it blocks when called from the call_back, unless I use again gdk_threads_enter and gdk_threads_leave, but you said I should not use gdk_threads_enter and leave.

Who is online

Users browsing this forum: No registered users and 4 guests

You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot post attachments in this forum