并发编程

原创 2015年07月31日 00:31:00

并发:如果两个程序的逻辑流在时间上有重叠,我们称这两个程序是并发的。

并发分为两类:内核级并发和应用级并发。

内核级并发:操作系统用来同时运行多个应用程序、实现多任务的机制。

应用级并发:应用程序同时完成多个功能叫做应用级并发,使用应用级并发的程序称为并发程序

操作系统提供了三种构造并发程序的方法:

进程:每个逻辑控制流都是一个进程,由内核调度和维护,进程有自己独立的虚拟内存空间,与其他流通信需要进程间通信进制支持。

I/O多路复用:应用程序在一个进程的上下文中显式地调度它们自己的逻辑流。因为程序是一个单独的进程,所以所有流共享同一个地址空间

线程:线程是运行在单一进程上下文中的逻辑流,因此所有流共享同一个虚拟地址空间,但是它由内核调度

一、基于进程的并发编程

构造并发程序最简单的方法就是用进程,使用fork、exec和waitpid等函数实现进程控制。事实上,由fork函数产生的子进程和父进程就是并发运行的。

使用进程进行并发编程的优点:由于每个进程有自己独立的地址空间,所以一个进程不可能会不小心覆盖另一个进程的虚拟存储器。

缺点:进程间共享状态信息(通信)非常困难;而且进程速度很慢,因为进程控制和IPC(进程间通信)的开销很高。

二、基于I/O多路复用的并发编程

I/O多路复用技术基本思路是使用select函数,要求内核挂起进程,只有在一个或多个I/O事件发生后,才将控制返回给应用程序。

实例代码:

port = atoi(argv[1]);
listenfd = Open_listenfd(port);//一个监听描述符
FD_ZERO(&read_set);//创建一个空的读集合
FD_SET(STDIN_FILENO,  &read_set);//在读集合中增加描述符0(标准输入)
FD_SET(listenfd, &read_set);//在读集合中增加描述符3(监听描述符)
ready_set = read_set;
Select(listenfd+1, &ready_set, NULL, NULL, NULL);//调用select函数,此函数会一直阻塞,直到标准输入或监听描述符准备好已读
if(FD_ISSET(STDIN_FILENO, &ready_set))//判断具体是哪一个描述符准备好已读,调用相应代码
{}
if(listenfd, &ready_set))
{}
I/O多路复用技术的优点:通过显式地调度流,给了程序员更多的对程序行为的控制方法;此外,由于其是运行在单一进程上下文中的,因此每个逻辑流都能访问该进程的全部地址空间,这使得在流之间共享数据变得很容易。

缺点:编码复杂,不能充分利用多核处理器。
三、基于线程的并发编程

线程是运行在进程上下文中的逻辑流,是上述两种方法的混合。

同进程一样,线程由内核自动调度,并且内核通过一个整数ID来识别线程。同基于I/O多路复用的流一样,多个线程运行在单一进程的上下文中,因此共享这个进程虚拟地址空间的整个内容。

多线程的执行模型和多进程的执行模型是相似的,它们都有自己的上下文,线程/进程切换时需要进行上下文切换。

线程执行和进程执行的不同:线程的上下文切换要比进程快得多;线程不是按照严格的父子层次来组织的,和一个进程相关的线程组成一个对等的线程池,主线程和其他线程的唯一区别在于它是进程中第一个运行的线程,一个线程可以杀死它的任意对等线程,或者等待它的任意对等线程终止。

Posix线程是在C语言中处理线程的一个标准接口。示例:

#include "csapp.h"
void *thread(void *vargp);
int main()
{
	pthread_t tid;
	Pthread_create(&tid, NULL, thread, NULL);
	Pthread_join(tid, NULL);
	exit(0);
}
void *thread(void *vargp)
{
	printf("Hello,world!\n");
	return NULL;
}
1、创建线程

线程通过调用pthread_create函数创建其他线程。

int pthread_create(pthread_t *tid, pthread_attr_t *attr, func *f, void *arg);//若成功则返回0,失败则返回非0
其中tid在调用结束后保存新创建线程的ID,attr用来改变创建线程的默认属性,f是新创建线程的入口地址,arg是新创建线程的输入变量。

2、终止线程

a)、顶层的线程返回时,线程会隐式地终止。

b)、通过调用pthread_exit函数,线程会显式地终止。

c)、某个对的线程调用Unix的exit函数,该函数终止进程以及所有与该进程相关的线程。

d)、一个线程可以通过使用线程参数ID调用pthread_cancle函数来终止相应线程。

3、回收已终止线程的资源

线程通过pthread_join函数等待其他线程终止并回收已终止线程占用的所有存储器资源。

int pthread_join(pthread_t tid, void **thread_return);//若成功则返回0,若出错则为非零
注意:与进程不同,pthread_join函数只能等待一个指定的线程终止。
4、分离线程

可结合线程:能够被其他线程收回其资源和杀死。

分离的线程:不能被其他线程回收或杀死,它的存储器资源在它终止时由系统自动释放。

线程默认为可结合的,为了避免存储器泄露,每个可结合线程都应该被其他线程显示地收回,或者通过pthread_detach函数来被分离。

5、初始化线程

pthread_once函数允许初始化与线程例程相关的状态。

int pthread_once(pthread_once_t *once_control, void (*init_routine)(void));




Linux 并发编程小结

一、可重入函数: 可重入函数遵循以下三个特点。 1.函数中不能使用任何非const的静态或者全局变量。这个比较好理解,共享的变量要保证是无法被修改的,大家都只作读取操作,自然没有竞争的问题。 ...
  • joker0910
  • joker0910
  • 2012年07月09日 23:46
  • 4398

java并发编程1--尚学堂学习

1对象锁的同步和异步,同步排队,异步并发 2多个实例多个实例锁,static关键字的限定,变成了类锁,类锁只有一个。 3synchronized取得的锁是对象锁,一个锁会对应多个同步方法 4同步...
  • dgutliangxuan
  • dgutliangxuan
  • 2017年09月20日 08:43
  • 143

C++11 并发编程教程&学习笔记

C++11 并发编程教程&学习笔记 参考: 1、原文:http://baptiste-wicht.com/posts/2012/03/cpp11-concurrency-part1-st...
  • huhaijing
  • huhaijing
  • 2016年06月24日 19:07
  • 993

Java并发编程(一):并发编程的挑战

Java并发编程(一): 并发编程的挑战本文主要内容出自《Java并发编程的艺术》一书,是对该书内容的归纳和理解,有兴趣的朋友请购买正版阅读全部内容。 并发编程的目的是为了让程序运行的更快,但是并不是...
  • upshi
  • upshi
  • 2016年12月05日 21:50
  • 572

并发编程一:并发概念和基础

并发编程:并发概念和基础介绍当我们烧水的时候我们往往不是在旁边等着它烧开,而是在它烧开之前我们也许会做些其它的事情比如看书、看会儿电视, 一旦水烧开了我们就去处理烧开的水(比如泡茶)。这也体现出我们...
  • nicewuranran
  • nicewuranran
  • 2016年08月11日 21:25
  • 746

【Java并发编程】并发编程大合集

转载请注明出处:http://blog.csdn.net/ns_code/article/details/17539599       为了方便各位网友学习以及方便自己复习之用,将Java并发编程系列...
  • mmc_maodun
  • mmc_maodun
  • 2013年12月27日 08:38
  • 40360

并发编程2:认识并发编程的利与弊

读完本文你将了解: 多线程的优点 1提高资源利用率 2响应更快 多线程的缺点 1增加资源消耗 2上下文切换的开销 3设计编码测试的复杂度增加 Java 内存模型与 CPU 内存简介 Java 中的堆 ...
  • u011240877
  • u011240877
  • 2017年03月01日 00:31
  • 6305

Java并发编程 01 并发注意事项

做并发编程的时候需要注意哪些事项呢? 上下文开销 CPU的线程是通过调度算法分配不同的时间片,当一条线程的时间片用完后,操作系统会暂停该线程,并保存该线程相应的信息,然后再随机选择一条新线程去...
  • JackZhang_123
  • JackZhang_123
  • 2017年10月04日 20:07
  • 72

为什么需要使用并发编程?什么时候适合使用并发编程技术?

并发编程又叫多线程编程。 在程序中,往往有很多很耗时的工作,比如上传文件、下载文件、跟客户聊天需要长时间建立连接。这种时候,一个线程是服务不了多个用户的,会产生因为资源独占产生的等待问题。 例如:编写...
  • sinat_20265495
  • sinat_20265495
  • 2016年09月09日 10:16
  • 1102

java程序员面试——Java并发编程知识点总结

1) 什么是线程?   线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。程序员可以通过它进行多处理器编程,你可以使用多线程对运算密集型任务提速。比如,如果一...
  • sbq63683210
  • sbq63683210
  • 2016年06月12日 12:16
  • 642
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:并发编程
举报原因:
原因补充:

(最多只允许输入30个字)