多线程
总阅读次
- 什么是进程?
- 什么是线程?
- 进程跟线程的关系?
- 引进线程的优点?
基本概念
preemptive multitasking
抢先式多任务:意思是操作系统能够强迫应用程序把CPU分享给其他人,程序员不需要额外的努力。
程序
只是一组指令的有序集合,它本身没有任何运行的含义,只是一个静态实体.
进程Process
是正在执行的程序实例。进程是程序在某个数据集上的执行,是一个动态实体。所以进程因创建才会产生,调度才会运行,所以进程会因等待资源或事件而被处于等待状态,一旦完成任务而被撤消,进程反映了一个程序在一定的数据集上运行的全部动态过程
。
逻辑上将一个进程划分为一下几段:
文本:程序的指令
数据:程序使用的静态变量
堆:程序可以从该区域动态分配额外内存
栈:随函数调用、返回而增减的一片内存,用于为局部变量和函数调用链接信息分配存储空间
thread
线程:是进程的一个实体,在一个程序中的多个执行路线就叫做线程。**每个线程都会执行相同的程序代码,共享统一数据区域和堆。可是每个线程都拥有自己的栈,用来状态本地变量和函数调用的链接信息.
** 线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
线程之间可通过共享的全局变量进行通信。借助于线程API所提供的条件变量和互斥机制,进程所属的线程之间得以相互通信并同步行为————尤其实在对共享变量的使用方面。
线程和进程的关系是
:线程是属于进程的,是CPU调度和分派的基本单位。**线程运行在进程空间内,同一进程所产生的线程共享同一内存空间,当进程退出时该进程所产生的线程都会被强制退出并清除。
**
线程可与属于同一进程的其它线程共享进程所拥有的全部资源,但是其本身基本上不拥有系统资源,只拥有一点在运行中必不可少的信息(如程序计数器、一组寄存器和栈)。
所有的进程至少有一个执行线程。
多线程,使程序得以将其工作分开,独立运作,不互相影响
线程函数、实例程序说明
-
pthread_create
pthread_create
作用是创建一个新线程;
函数原型1
2
3
int pthread_create(pthread_t *thread,pthread_attr_t *attr,void *(*start_routine)(void *),void *arg);第一个参数
pthread_t *thread
:线程被创建时候这个指针指向的变量中将被写入一个线程号,我们用线程号来引用新的线程。第二个参数
pthread_attr_t *attr
用于设置线程的属性;一般不需要设置特殊的属性,所以我们设置该参数为NULL最后2个参数分别告诉线程将要启动执行的函数
void *(*start_routine)(void *)
该函数以一个指向void的指针为参数,返回的也是一个指向void的指针。因此可以传递一个任一类型的参数并返回一个任一类型的指针。
和:传递给函数的参数void *arg
该函数调用成功时返回值是0,如果失败则返回错误代码
pthread_join
prhread_join
的作用是使一个线程等待另一个线程结束。这个函数的定义如下:1
2
int pthread_join(pthread_t th,void **thread_return );第1个参数:指定了将要等待的线程,线程通过pthread_crtate返回的标识符来指定。
第2个参数:是一个指针,它指向另一个指针,而后者指向线程的返回值。与
pthread_create
类似,这个函数在成功时返回0,失败时返回错误代码。
在Linux中,新建的线程并不是在原先的进程中,而是系统通过一个系统调用clone()。该系统copy了一个和原先进程完全一样的进程,并在这个进程中执行线程函数。不过这个copy过程和fork不一样。 copy后的进程和原先的进程共享了所有的变量,运行环境。这样,原先进程中的变量变动在copy后的进程中便能体现出来。
代码中如果没有pthread_join主线程会很快结束从而使整个进程结束,从而使创建的线程没有机会开始执行就结束了。加入pthread_join后,主线程会一直等待直到等待的线程结束自己才结束,使创建的线程有机会执行。
所有线程都有一个线程号,也就是Thread ID。其类型为pthread_t。通过调用pthread_self()函数可以获得自身的线程号。
pthread_exit
线程通过pthread_exit
函数终止执行;这个函数的作用是,终止调用它的线程并返回一个指向对象的指针。
函数原型
1 |
|
- 简单的线程程序:
1 | /*这个程序创建了一个新线程,新线程与原先的线程共享变量,并在结束的时候向原先的线程返回一个结果*/ |
- 2个线程同时执行每个线程通过设置run_now变量的方法通知另一个线程开始运行,然后,它会等待另一个线程改变了这个变量的值后再次运行。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
void *thread_function(void *arg);
int run_now = 1;
char message[] = "Hello World";
int main() {
int res;
pthread_t a_thread;
void *thread_result;
int print_count1 = 0;
res = pthread_create(&a_thread, NULL, thread_function, (void *)message);
if (res != 0) {
perror("Thread creation failed");
exit(EXIT_FAILURE);
}
while(print_count1++ < 20) { // 这个while循环 只输出1次 1
if (run_now == 1) {
printf("1");
run_now = 2;
}
else {
sleep(1);
}
}
printf("\nWaiting for thread to finish...\n");
res = pthread_join(a_thread, &thread_result);
if (res != 0) {
perror("Thread join failed");
exit(EXIT_FAILURE);
}
printf("Thread joined %s\n", (char *)thread_result);
exit(EXIT_SUCCESS);
}
void *thread_function(void *arg) {
int print_count2 = 0;
while(print_count2++ < 20) {
if (run_now == 2) {
printf("2");
run_now = 1;
}
else {
sleep(1);
}
}
sleep(3);
pthread_exit("*******EOF*****");
}这2个线程共享run_now变量
C++11多线程