• UNIX 网络编程之线程


     概述:

       实现并发服务器一般都是父进程accept一个连接,然后fork一个子进程,该子进程处理与该连接对端的客户之间的通信。但是fork是昂贵,耗资源和时间。而线程是轻量级线程,它的创建比进程的创建块10-100倍。在同一进程内除了共享全局变量外还共享:

     大多数数据;进程指令; 打开的文件; 信号处理函数信号处置; 当前工作目录;用户ID和组ID

    不过每个线程有各自的资源:‘

     线程ID; 寄存器集合了栈了errno; 信号掩码; 优先级

    基本线程函数:创建和终止

      pthread_create函数

      #include <pthread.h>

      int pthread_create(pthread_t *tid, const pthread_attr_t *attr, void *(*func)(void *), void *arg);

     一个进程的每个线程都由一个线程ID标识。每个线程有很多属性,比如优先级大小,初始栈大小,是否应该成为一个守护线程等等


      pthread_join函数

     #include <pthread.h>

      int pthread_join(pthread_t *tid, void **status);

      该函数类似与waitpid


      pthread_self函数

       #include <pthread.h>
      int pthread_self(void);

      每个线程使用pthread_self获得自身的线程ID


     pthread_detach函数

     #include <pthread.h>

      int pthread_detach(pthread_t tid);

      一个线程或者是可汇合的,或者是脱离的。当一个可汇合的线程终止时,它的线程ID和退出状态将留存到另一个线程对它调用pthread_join。脱离的线程像守护线程,当他们终止时,所有相关资源都被释放.


     pthread_exit函数

      

     #include <pthread.h>

      int pthread_exit(void *status);

    结束一个线程


    互斥锁的使用

    多线程程序的经典问题:多个线程同时修改一个共享变量(如全局变量)

     

    #include <pthread.h>
    #include <stdio.h>
    
    int counter;
    void *doit(void*);
    
    int main(int argc, char **argv)
    {
    	pthread_t tidA, tidB;
    
    	pthread_create(&tidA, NULL, &doit, NULL);
    	pthread_create(&tidB, NULL, &doit, NULL);
    
    	pthread_join(tidA, NULL);
    	pthread_join(tidB, NULL);
    	return 0;
    }
    
    void *doit(void * arg)
    {
    	int i, val;
    	for(i=0; i<10; i++)
    	{
    		val = counter;
    		printf("counter is %d
    ", val+1);
    		counter = val+1;
    	}
    	return NULL;
    }
    

    上面程序的运行结果并不是我们想要的结果,因为线程的运行是并发运行的,也就是说counter值的修改的结果是不定的,以下为运行结果


    所以我们应该引入同步机制,首先使用互斥量实现

     

    #include <pthread.h>
    #include <stdio.h>
    
    int counter;
    pthread_mutex_t counter_mutex;
    
    void *doit(void*);
    
    int main(int argc, char **argv)
    {
    	pthread_t tidA, tidB;
    
    	pthread_create(&tidA, NULL, &doit, NULL);
    	pthread_create(&tidB, NULL, &doit, NULL);
    
    	pthread_join(tidA, NULL);
    	pthread_join(tidB, NULL);
    	return 0;
    }
    
    void *doit(void * arg)
    {
    	
    	int i, val;
    	for(i=0; i<10; i++)
    	{
    		pthread_mutex_lock(&counter_mutex);
    		val = counter;
    		printf("counter is %d
    ", val+1);
    		counter = val+1;
    		pthread_mutex_unlock(&counter_mutex);
    	}
    	return NULL;
    }
    


    使用在对counter值进行修改之前进行上锁操作,修改之后,进行解锁操作


  • 相关阅读:
    Flink读取Kafka数据,进行汇总
    Flink集成到CDH上,并运行一个例子
    CDH6.2安装配置第三篇:前台页面配置讲解
    LINUX之ntp时间同步服务配置
    Dubbo+Zookeeper(一)Zookeeper初识
    SpringCloud(五)Zuul网关与分布式配置中心
    SpringCloud(四)Hystrix熔断器
    SpringCloud(三)Ribbon与Feign
    SpringCloud(二)服务注册与发现
    多线程与高并发(六) Lock
  • 原文地址:https://www.cnblogs.com/riskyer/p/3281225.html
Copyright © 2020-2023  润新知