在linux或者unix环境中,errno是一个十分重要的部分。在调用的函数出现问题的时候,我们可以通过errno的值来确定出错的原因,这就会,这样就能够保证不会有竞争条件的出现。一般而言,编译器会自动保证errno的安全性,但是为了妥善期间,我们希望在写makefile的时候把_LIBC_REENTRANT宏定义,比如我们在检查<bits/errnoh文件中发现如下的定义:# ifndef __ASSEMBLER__/ Function to get address of global `errno' variable /extern int __errno_location (void) __THROW __attribute__ ((__const__));# if !defined _LIBC || defined _LIBC_REENTRANT/ When using threads, errno is a per-thread value /# define errno (__errno_location ())# endif# endif / !__ASSEMBLER__ /#endif / _ERRNO_H /也就是说,在没有定义__LIBC或者定义_LIBC_REENTRANT的时候,errno是多线程/进程安全的。一般而言,__ASSEMBLER__, _LIBC和_LIBC_REENTRANT都不会被编译器定义,但是如果我们定义_LIBC_REENTRANT为了检测一下你编译器是否定义上述变量,不妨使用下面一个简单程序。#include <stdioh#include <errnohint main( void ){#ifndef __ASSEMBLER__printf( Undefine __ASSEMBLER__/n );#elseprintf( define __ASSEMBLER__/n );#endif#ifndef __LIBCprintf( Undefine _LIBC_REENTRANT/n );#elseprintf( define _LIBC_REENTRANT/n );#endifreturn 0;}希望读者在进行移植的时候,读一下相关的unix版本的<bits/errnoh
目测是线程退出时没有解开互斥锁,导致其它线程一直在等互斥锁被解开。
以下是修改后的thrd_func函数代码:
//线程函数入口void thrd_func(void arg)
{
int thrd_num = (int)arg;
int delay_time = 0;
int count = 0;
int res;
res = pthread_mutex_lock(&mutex);//互斥锁上锁
if(res)
{
printf("Thread %d lock failed\n",thrd_num);
pthread_exit(NULL);
}
printf("Thread %d is starting\n",thrd_num);
for(count = 0;count < REPEAT_NUMBER;count++)
{
delay_time = (int)(rand()%5);//随机时间数
sleep(delay_time);
printf("\tThread %d: job %d delay =%d\n",thrd_num,count,delay_time);
}
pthread_mutex_unlock(&mutex); // 解开互斥锁
printf("Thread %d finished\n",thrd_num);
pthread_exit(NULL);
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)