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

来源:互联网 发布:xps分析软件下载 编辑:程序博客网 时间:2024/05/21 13:29
        今天研究下线程安全函数和非线程安全函数。什么是线程安全函数?我们知道在多线程编程中,线程安全问题是不容忽视的。只要存在多线程,就会存在多个线程访问同一段代码或者同一个全局变量的临界区,对于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 0
原创粉丝点击