免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3477 | 回复: 12
打印 上一主题 下一主题

在我的项目中的多线程程序中遇到一个问题,请大家帮助 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-01-19 23:17 |只看该作者 |倒序浏览
在我的项目中遇到了一个多线程的问题,为了简化问题,我写了个简单的例程来
说明,操作系统是Red hat 9,2.4.20的内核,我的例程如下:

#include <pthread.h>
#include <stdio.h>
#include <sys/time.h>

void *thread_func(void *arg);

int main(){
        pthread_t th;
        int *exitcode,
        pthread_create(&th,NULL,thread_func,NULL);
        pthread_join(th,NULL);
        printf("Child thread exit.");
        return;
}
void *thread_func(void *arg){
        struct timespec abstime;
        struct timeval nowtime;
        pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
    pthread_cond_t PTHREAD_MUTEX_INITIALIZER;
    gettimeofday(&nowtime,NULL);
        abstime.tv_sec=nowtime.tv_sec+3;
        abstime.tv_nsec=0;
        printf("Child thread waiting...\n");
               
        pthread_mutex_lock(&mutex);
        pthread_cond_timedwait(&cond,&mutex,&abstime);
        pthread_mutex_unlock(&mutex);
        printf("Child thread after waiting 3 seconds.\n");
        pthread_exit(NULL);
//      return ((void *)1);
}

程序的功能是在主线程中产生一个子线程,子线程函数就是thread_func,
主线程产生子线程之后调用pthread_join来等待子线程的结束。而子线程的
功能就是利用pthread_cond_timedwait这个函数来等待3秒后用pthread_exit
退出。
至于这里为什么用了互斥锁和条件变量,以及用pthread_cond_timedwait
来等待,这是我项目中的问题简化,这里只是作为示例来说明。
将以上程序编译后:gcc -o test test.c -lpthread   ,
然后运行  ./test
输出结果为:
Child thread waiting...
Child thread after waiting 3 seconds.
段错误

我的问题就是在子线程用pthread_exit退出后,产生了段错误。而使用return 退出 ,
就是我程序中注释掉的部分,这样的话,就不会有段错误。
同样,若是我把pthread_cond_timedwait这一行程序注释掉,程序也不会出错,
这是为什么呢?

我的结论是,子线程中,pthread_cond_timedwait和pthread_exit不能同时使用,但
这个解释太勉强了,不能说明真正原因。而且道理上子线程用pthread_exit和return
退出,都是一样的,但是为什么一个会产生段错误,而另一个却不会。

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
2 [报告]
发表于 2007-01-20 09:02 |只看该作者

  1. #include <pthread.h>
  2. #include <stdio.h>
  3. #include <sys/time.h>

  4. void *thread_func(void *arg);

  5. int main()
  6. {
  7.     pthread_t th;
  8.     pthread_create(&th,NULL,thread_func,NULL);
  9.     pthread_join(th,NULL);
  10.     printf("Child thread exit.\n");
  11.     return 0;
  12. }
  13. void *thread_func(void *arg){
  14.     struct timeval nowtime;
  15.     struct timespec abstime;

  16.     pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
  17.     pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

  18.     gettimeofday(&nowtime,NULL);
  19.     abstime.tv_sec=nowtime.tv_sec+3;
  20.     abstime.tv_nsec=0;
  21.     printf("Child thread waiting...\n");

  22.     pthread_mutex_lock(&mutex);
  23.     pthread_cond_timedwait(&cond,&mutex,&abstime);
  24.     pthread_mutex_unlock(&mutex);
  25.     printf("Child thread after waiting 3 seconds.\n");
  26.     pthread_exit(NULL);
  27.     //return ((void *)1);
  28. }
复制代码


我修改了一下,没发现任何问题.

论坛徽章:
0
3 [报告]
发表于 2007-01-20 10:13 |只看该作者
pthread_cond_t PTHREAD_MUTEX_INITIALIZER;

编译能通过么?

论坛徽章:
0
4 [报告]
发表于 2007-01-20 10:26 |只看该作者
====

楼主应该仔细一些。

====

论坛徽章:
0
5 [报告]
发表于 2007-01-20 12:15 |只看该作者
哦,那是我贴上去的时候,修改代码格式时不小心删除了
原程序应该是pthread_t cond=PTHREAD_MUTEX_INITIALIZER;
请问mq110  版主-法师你能正常运行我的程序吗。

论坛徽章:
0
6 [报告]
发表于 2007-01-20 12:19 |只看该作者
原帖由 柳五随风 于 2007-1-20 10:13 发表
pthread_cond_t PTHREAD_MUTEX_INITIALIZER;

编译能通过么?


回这位兄弟的话,这是我发贴时的失误,不是我原来程序中的问题,不好意思。
编译没有任何问题,运行时就出现了我所说的错误,
但一量将pthread_exit(NULL)改成return(NULL),
就没有段错误出现。
或是注释掉:pthread_cond_timedwait这个函数所在行,也没有问题

论坛徽章:
0
7 [报告]
发表于 2007-01-20 13:15 |只看该作者
原帖由 aboytom 于 2007-1-20 12:19 发表


回这位兄弟的话,这是我发贴时的失误,不是我原来程序中的问题,不好意思。
编译没有任何问题,运行时就出现了我所说的错误,
但一量将pthread_exit(NULL)改成return(NULL),
就没有段错误出现。
或是注释 ...

c/C++? condition 又没有可能被release多次?你写上的代码没有问题。

论坛徽章:
0
8 [报告]
发表于 2007-01-20 14:17 |只看该作者
原帖由 柳五随风 于 2007-1-20 13:15 发表

c/C++? condition 又没有可能被release多次?你写上的代码没有问题。


嗯,是C,
我觉得我的代码也没有什么问题,但结果莫名其妙,不知道是不是操作系统的问题。
thanks

论坛徽章:
0
9 [报告]
发表于 2007-01-20 16:17 |只看该作者
pthread_exit和return
我手上没有unix手册,应该不一样的,估计一个是安全退出,一个强行退出
比如:一个程序,你用ctrl+c退出,没有问题,但是给程序发送一个信号量abc,让程序退出,但是程序如果有问题,很可能就退不出去,和你的分析一样,可能出在pthread_cond_timedwait

论坛徽章:
0
10 [报告]
发表于 2007-01-20 18:41 |只看该作者

  1.     pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
  2.     pthread_cond_t PTHREAD_MUTEX_INITIALIZER;
复制代码

有一点疑问:如果你的互斥量和条件变量均定义为局部变量,那么每个线程使用各自的互斥量和条件变量,如果线程间使用共享的数据,那么对于共享数据的互斥访问是不可能实现的,因为各线程使用各自的互斥量,加锁操作都会成功.通过加锁进行互斥,应当针对的是同一个锁.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP