网络编程(36)—— 线程安全函数和非线程安全函数

        今天研究下线程安全函数和非线程安全函数。什么是线程安全函数?我们知道在多线程编程中,线程安全问题是不容忽视的。只要存在多线程,就会存在多个线程访问同一段代码或者同一个全局变量的临界区,对于uc中标准函数也是一样(类似于windows中的原子函数)。当多个线程同时调用一个标准函数时,执行同一段代码,同样会在函数内部形成临界区,就可能出现问题。
        线程安全函数就是针对上述问题,在函数内部做了特殊的处理。用一句话总结:线程安全函数就是在多线程同时被调用时不会引发问题的函数,而非线程安全函数是在同时被调用时引发问题的函数。以一个函数为例,用来获取域名对应的ip信息的下面函数就是非线程安全函数:
struct hostent* gethostbyname(const char* hostname);

        而其对应的线程安全函数是:
int gethostbyname_r(const char *name,
struct hostent *ret, char *buf, size_t buflen,
struct hostent **result, int *h_errnop);

        线程安全函数的后缀名通常是_r,那么以后再多线程中我们就应该使用gethostbyname_r来代替gethostbyname?按理来说是这样,但是使用gethostbyname_r明显会带来较大的工作量。幸好,我们可以通过在声明头文件前声明一个宏_REENTRANT,使得我们在使用gethostbyname时,会自动被gethostbyname_t替代,也就是说像以下示例代码一样:
#define _REENTRANT
#include<stdio.h>
#include<pthread.h>
#include<netdb.h>
void* pthread_main(void* param)
{
    struct hostent* pent;
    char* name = (char*)param;
    pent=gethostbyname(name);
    printf("the ip is: %s \n",
			inet_ntoa(*((struct in_addr*)pent->h_addr_list[0])));
}
int main()
{
	int i=0;
	pthread_t pid[2];
	char* name1="localhost";
	char* name2="www.baidu.com";
	pthread_create(&pid[0],NULL,(void*)pthread_main,(void*)name1);
	pthread_create(&pid[1],NULL,(void*)pthread_main,(void*)name2);
	for(i=0;i<2;i++)
	{
		pthread_join(pid[i],NULL);
	}
    return 0;
}



        当然如果还觉得麻烦,不想在代码里面声明宏_REENTRANT,我们在进行编译程序时,把宏加上去也可:
gcc test.cpp -D_REENTRANT -lpthread


Github位置:
https://github.com/HymanLiuTS/NetDevelopment
克隆本项目:
git clone git@github.com:HymanLiuTS/NetDevelopment.git
获取本文源代码:
git checkout NL36


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值