• C复习篇 使用Posix标准线程库 Porgramming with Pthread


     Programming with pthread?  what is Pthread?

     Pthread,作为C/C++编程的标准线程库,其实它是POSIX Standard thread library.

     

      那么,怎么去理解POSIX标准呢?

      下面给一些资料的链接,有兴趣的可以自己去查看.

       1. http://zh.wikipedia.org/wiki/POSIX

       2. standards.ieee.org/findstds/standard/1003.1-2008.html

       3. www.opengroup.org/austin/papers/posix_faq.html

       4. www.unix.org/version3/ieee_std.html

     

      在哪里可以找到Pthread的源码实现呢?

           如果有需要,想要扫盲或者是去学习Pthread,那么你可以去下载glibc的源码,其中包含Pthread的实现.

             GNU的ftp站点链接: http://ftp.gnu.org/gnu/glibc

     

     Pthread APIs:

           Pthread API可以分为下面四个部分:

                  1.  Thread Management(线程管理): 对线程的操作,像创建,挂起,连接等,还包括部分对线程属性的操作.

                  2.  Mutexes: 互斥锁,提供对同步的支持.

                  3.  Condition Vars:条件锁,在共享互斥锁的线程之间通信.

                  5.  Sync: 管理同步

    关于Pthread的下中文学习资料还是很多的,所以在这里我就不过多介绍那些学习方面的知识了。如果你是新手的话,

    那么还是请你去参阅了相关资料和书籍之后再自行学习.请原谅~


    关于pthread_exit 和 pthread_join.

        记得考试前有一天,研究生师兄问我一个问题:他说他在使用Pthread库的时候,创建的worker线程不工作,让我帮

    他解决一下这个问题. 现在我已经忘记了他当时写的代码了,不过问题我还记得,所以可以用另外一个小例子代替:

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <pthread.h>
    
    #define THREAD_NUMS 20
    
    
    //worker
    void *Greeting(void * msg);
    
    
    int main(int args, char ** argv)
    {
            pthread_t workers[THREAD_NUMS];
    
    	int retval;
    
    	int index;
    
            char *msg = "Hello Pthread!";
    
    	for(index = 0; index < THREAD_NUMS; index++)
    	{
    		retval = pthread_create(&workers[index],NULL,Greeting,(void*)msg);
    
    		if(retval == -1)
    		{
    			printf("%s\n","error!");
    			exit(-1);
    		}
    	
    	}
    
    //	pthread_exit(NULL);      
    
    	return EXIT_SUCCESS;
    }
    
    
    void *Greeting(void * msg)
    {
    
       printf("Thread #%ld,Greeting %s\n",(long)pthread_self(),(char*)msg);
    	
       usleep(1000000);
    }
    

     看到上面的代码中我注掉了pthread_exit(NULL),  其实很简单就可以预知这个小程序会出现什么样的情况. 就是只有一部分被创建的线程完成

     了指定的工作,另外的线程在完成工作之前,已经失去了运行的环境,因为主线程已退出了.

      好了,下面就是pthread_exit(NULL)的作用了,它就是等待所有子线程退出.

      而pthread_join和pthread_exit的作用差不多,不过可以从退出的子线程获取退出状态码.

     

    注意互斥锁的使用:

      当使用share memory的方式进行线程之间通信的时候,对共享区域的一切数据写操作都需要进行锁处理. 当然读操作不需要~

      常见的使用方式如下:

    pthread_mutex_lock(&mutex);
    
    //
    // ...
    //
    
    pthread_mutex_unlock(&mutex);
    

     在锁竞争的时候,至于使用互斥锁的时候,哪条线程在竞争锁的时候会胜出? 这个问题涉及到线程的优先级调度,如果没有设置使用优先级调度

    策略的话,那么锁的获取是随机的,也就是不可预知的.

     

    互斥锁和条件锁搭档使用:

        在对于条件锁的操作函数中,很多都是和互斥锁相关的,需要搭档使用. 如果只是用互斥锁的话,就像上面说的那样子,没有使用优先级调度的

    情况下,线程获取锁的可能是无法预知的,从另外一个角度说,我们无法做到指定线程之间的通信。 例如A线程完成之后需要指定B线程去完成某件

    工作,如果只是使用互斥锁的话,这是无法完成的,因为无法保证在A线程释放锁之后,B就可以立即获得锁。所以这个时候就需要使用条件锁。

    条件锁使用的形式一般如下:

     

    void *thread_work_func1(void *parm)
    {
    
    	for(;;)
    	{
    
    		pthread_mutex_lock(&mutex);
    	
    		if(xxxx)
    		{
    		    pthread_cond_signal(&condition);
    		}else
    		{
    		    // ....
    		}		
    	
    		pthread_mutex_unlock(&mutex);
    
    	}
    
    }
    
    
    void *thread_work_fun2(void *parm)
    {
    
    	for(;;)
    	{
    	
    		pthread_mutex_lock(&mutex);
    		
    		pthread_cond_wait(&condition,&mutex);
    		
    		// do something...
    
    		pthread_mutex_unlock(&mutex);
    
    	}
    
    
    
    }
    

      由于后面需要阅读glib的源码,其中的线程有些是关于pthread,所以就复习一下。在后续的文章中,我还会再介绍pthread.

      到时会考虑写的详细一点.

     
  • 相关阅读:
    sql语句
    数据结构
    Collection接口
    【学习笔记】〖九度OJ〗题目1443:Tr A
    【学习笔记】〖九度OJ〗题目1104:整除问题
    【学习笔记】〖九度OJ〗题目1138:进制转换
    【学习笔记】〖九度OJ〗题目1326:Waiting in Line
    【学习笔记】〖九度OJ〗题目1437:To Fill or Not to Fill
    【学习笔记】〖九度OJ〗题目1153:括号匹配问题
    【学习笔记】〖九度OJ〗题目1161:Repeater
  • 原文地址:https://www.cnblogs.com/respawn/p/2581638.html
Copyright © 2020-2023  润新知