QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 861|回复: 9

关于glade中的线程问题

[复制链接]
发表于 2004-5-17 09:39:19 | 显示全部楼层 |阅读模式
现在在用glade做一个linux下的网络聊天室,用到线程技术,碰到的问题是,线程的调用函数中显示 窗口或按钮时,有时能成功显示,有时又不能显示出来.下面这段代码是线程调用的函数中的一部分,通过调试已经知道能执行到gtk_widget_show及其以后的代码,但是按钮button3,button4等有时能显示,有时却不能,不知为何?请指点!!谢谢
  switch(usercode){
case 1:
        gtk_button_set_label(GTK_BUTTON(button3),"usr1");
        gtk_widget_show(button3);
printf("after show!");
        sendto(s,dgram1,sizeof(dgram1),0,(struct sockaddr *)&bcadr_inet,len_inet);
        break;
case 2:
        gtk_button_set_label(GTK_BUTTON(button4),"usr2");
        gtk_widget_show(button4);
        sendto(s,dgram1,sizeof(dgram1),0,(struct sockaddr *)&bcadr_inet,len_inet);
        break;
case 3:
        gtk_button_set_label(GTK_BUTTON(button5),"user3");
        gtk_widget_show(button5);
        sendto(s,dgram1,sizeof(dgram1),0,(struct sockaddr *)&bcadr_inet,len_inet);
        break;
       }
发表于 2004-5-17 10:00:44 | 显示全部楼层
http://www.softhouse.com.cn/linux/knowledge/tech/gtk_faq/gtkfaq-4.html
回复

使用道具 举报

 楼主| 发表于 2004-5-17 11:15:57 | 显示全部楼层
是不是在GTK中用线程显示图形有需要特别注意的地方?我用了互斥锁了,结果还是一样,有时可以,有时不可以!!
回复

使用道具 举报

发表于 2004-5-17 13:08:00 | 显示全部楼层
看一下这儿:
http://www.cpsc.ucalgary.ca/Help/unixsoftware/prog/api_docs/gdk-2.0/gdk-threads.html

在你的线程内调用 gtk_*函数的片断前后加上  gdk_threads_enter (); gdk_threads_leave ();

你这里就加在 switch 前后吧. 试试.
回复

使用道具 举报

 楼主| 发表于 2004-5-17 16:40:16 | 显示全部楼层
加上gdk_threads_enter和gdk_threads_leave 之后还是不行,问题和原来的一样.

我的程序大体是这样的,一个服务器程序,一个客户端程序.两个程序各自都调用一个线程函数,客户端的线程函数是一个无限循环,循环体是一个接收函数,时刻准备接收从服务器发来的消息,再将消息作为一个按钮的标签,显示按钮,同时向服务器发送一条消息.服务器程序类似,将从客户端发来的消息作为一个按钮的标签,显示按钮.
这两个线程是随客户端或服务器的程序运行而产生的.

这样属于两个不同进程的线程,在显示按钮时会产生冲突吗??
回复

使用道具 举报

发表于 2004-5-17 19:08:08 | 显示全部楼层
如果实在不行,把你的程序简化一下,发上来吧,让大家看看。
回复

使用道具 举报

 楼主| 发表于 2004-5-19 09:00:30 | 显示全部楼层
while(1)
{
   z=recvfrom(s,dgram1,sizeof(dgram1),0,(struct sockaddr *)&clntadr_inet,&len_inet); //user login!  
   dgram=dgram1;
if(!strcmp(dgram,"login"))
       {
        usercode++;
//发送用户登录信号"login":
        sendto(s,dgram1,sizeof(dgram1),0,(struct sockaddr *)&bcadr_inet,len_inet);
   //接收用户名:
        z=recvfrom(s,dgram1,sizeof(dgram1),0,(struct sockaddr *)&clntadr_inet,&len_inet);
        strcpy(userstrack[usercode],dgram1);
   printf("the userstrack[%d] is: %s\n",usercode,userstrack[usercode]);
        uname[usercode]=dgram1;
   printf("the uname[%d] is : %s\n",usercode,username[usercode]);
        user=usercode;
        usernum1[0]=user;
//发送在线用户数:
        sendto(s,usernum1,sizeof(usernum1),0,(struct sockaddr *)&bcadr_inet,len_inet);
        z=recvfrom(s,dgram2,sizeof(dgram2),0,(struct sockaddr *)&clntadr_inet,&len_inet);
//发送所有在线用户的用户名:
        for(r=1;r<=usercode;r++)
         {
          sendto(s,userstrack[r],sizeof(userstrack[r]),0,(struct sockaddr *)&bcadr_inet,len_inet);
          z=recvfrom(s,dgram2,sizeof(dgram2),0,(struct sockaddr *)&clntadr_inet,&len_inet);
         }
//将最新登录的用户显示
        switch(usercode){
        case 1:
          gtk_button_set_label(GTK_BUTTON(button3),username[1]);
          gtk_widget_show(button3);         
          break;
        case 2:
          gtk_button_set_label(GTK_BUTTON(button4),username[2]);
          gtk_widget_show(button4);
          break;
        case 3:
          gtk_button_set_label(GTK_BUTTON(button5),username[3]);
          gtk_widget_show(button5);   
          break;
        case 4:
          gtk_button_set_label(button6,username[4]);
          gtk_widget_show(button6);        
          break;
        case 5:
          gtk_button_set_label(button7,username[usercode]);
          gtk_widget_show(button7);        
          break;      
        case 6:
          gtk_button_set_label(button8,username[usercode]);
          gtk_widget_show(button;        
          break;
        case 7:
          gtk_button_set_label(button9,username[usercode]);
          gtk_widget_show(button9);        
          break;
        case 8:
          gtk_button_set_label(button10,username[usercode]);
          gtk_widget_show(button10);     
          break;
        case 9:
          gtk_button_set_label(button11,username[usercode]);
          gtk_widget_show(button11);         
          break;
             } //the end of switch
}  //the end of if

else{   
    gtk_text_buffer_get_end_iter(buffer,&iter);
    gtk_text_buffer_insert(buffer,&iter,dgram,-1);
  sendto(s,dgram1,sizeof(dgram1),0,(struct sockaddr *)&bcadr_inet,len_inet);

  z=recvfrom(s,dgram1,sizeof(dgram1),0,(struct sockaddr *)&clntadr_inet,&len_inet);   // 's massege is :
    dgram=dgram1;
    gtk_text_buffer_insert(buffer,&iter,dgram,-1);
  sendto(s,dgram1,sizeof(dgram1),0,(struct sockaddr *)&bcadr_inet,len_inet);

  z=recvfrom(s,dgram1,sizeof(dgram1),0,(struct sockaddr *)&clntadr_inet,&len_inet);   // the user's massage
    dgram=dgram1;
    gtk_text_buffer_insert(buffer,&iter,dgram,-1);
  sendto(s,dgram1,sizeof(dgram1),0,(struct sockaddr *)&bcadr_inet,len_inet);

z=recvfrom(s,dgram1,sizeof(dgram1),0,(struct sockaddr *)&clntadr_inet,&len_inet);    // the face or picture
   dgram=dgram1;
   gtk_text_buffer_insert(buffer,&iter,dgram,-1);
sendto(s,dgram1,sizeof(dgram1),0,(struct sockaddr *)&bcadr_inet,len_inet);
  gtk_text_buffer_insert(buffer,&iter,"\n",-1);
}  
}

这是一个聊天室服务器程序的主要部分,程序中在线用户的用户名是写在按钮上,就是在显示按钮时,有时能成功,有时不能.不能显示时,通过在gtk_widget_show后面加一条printf语句,可以知道其实已经执行到了.请指教!
回复

使用道具 举报

发表于 2004-5-20 17:42:59 | 显示全部楼层
看不出来有何不对,但我想你是多线程,那其它的线程做什么呢?是否其它线程会偶尔占用Gtk资源(主要是这个button及其容器),这样,当其它线程使用占有Gtk资源时,你的button刷新就无法进行下去,而可以只有最后一个被刷新的值。不知道大体结构,不对再讨论。
回复

使用道具 举报

发表于 2004-5-21 11:29:08 | 显示全部楼层
试试在gtk_button_set_lable后加个
while (gtk_events_pending ())
          gtk_main_iteration ();
看行不?
回复

使用道具 举报

 楼主| 发表于 2004-5-24 09:24:13 | 显示全部楼层
这两条语句起什么作用?我用了,还是不能解决问题,
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-8 06:50 , Processed in 0.072673 second(s), 16 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表