一、线程的概念: 进程内部的一条执行序列,进程内部至少有一条执行线程,即main函数的执行体。 进程内部可以有多条线程,称为多线程, main 函数的线程称之为主线程, 其他线程称之为函数线程。 函数线程是由主线程通过系统调用函数创建的。
二、线程与进程的区别
1. 进程是资源分配的最小单位, 线程是调度(执行) 的最小单位。
2. 进程由两部分构成:进程内核对象,地址空间。线程也由两部分组成:线程内核对象,操作系统用它来对线程实施管理。线程堆栈,用于维护线程在执行代码时需要的所有函数参数和局部变量。
3. 进程间相互独立,同一进程的各线程间共享。某进程内的线程在其它进程不可见。
4. 进程间通信IPC,线程间可以直接读写进程数据段(如全局变量)来进行通信——需要进程同步和互斥手段的辅助,以保证数据的一致性。
5. 线程切换比进程切换消耗小。
6. 在多处理机系统中,对于传统的进程,即单线程进程,不管有多少处理机,该进程只能运行在一个处理机上。但对于多线程进程,就可以将一个进程中的多个线程分配到多个处理机上,使它们并行执行,这无疑将加速进程的完成。因此,现代处理机OS都无一例外地引入了多线程。
7. 一个线程只能属于一个进程,而一个进程可以有多个线程。
三、线程的分类
1. 用户级: 在用户空间是多线程的, 内核只识别进程整体。 线程创建、 管理、 销毁都是由用户空间负责, 用户通过调用库函数在完成。
2. 内核级: 线程的创建、 控制、 销毁都是由内核实现的, 每个线程对内核都是可见的。
3. 组合模型: 一部分是用户级, 一部分内核级线程。 介于内核级和用户级之间, 用户态创建多个线程, 内核看到的也是多个, 只是这是种 m: n 的对应关系。
四、怎样创建线程
库函数: int pthread_create();
五、线程运行特点:所有线程同时运行。
六、 线程怎么结束
进程: exit;
线程: pthread_exit();
线程怎么等待其他线程结束。
七、 线程间数据共享
1. 全局变量
2. 局部变量(栈区)
3. 堆区
4. 文件
八、代码
//基本的线程函数代码,主线程和函数线程的生成、输出
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <pthread.h>
int *s = NULL;
void * pthread_fun(void *arg)//线程函数
{
printf("pthread function start\n");
int i = 0;
for(; i < 5; ++i)
{
sleep(1);
printf("pthread function \n");
}
printf("a = %d\n", s[0]);
s[0] = 20;
}
void main()
{
printf("main start\n");
s = (int*)malloc(4);
s[0] = 10;
sleep(2);
pthread_t id;
int res = pthread_create(&id, NULL, pthread_fun, NULL);//生成线程,线程函数一般传参为NULL
assert(res == 0)
printf("pthread create success\n");
int i = 0;
for(; i < 3; ++i)
{
sleep(1);
printf("main pthread\n");
}
pthread_join(id, NULL);
/*pthread_join是为了防止主线程没有给其他线程执行的时间就返回了而设计的, pthread_join(thread_t th,void ** thread_return )是使主线程等待th线程运行结束再运行*/
printf("%d\n", s[0]);
}
/*生成两个函数线程,函数线程1是输出100以内所有的素数,函数2是对数组进行冒泡排序*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <pthread.h>
#include <math.h>
void *fun1(void *arg)
{
sleep(1);
pthread_t id = *(pthread_t*)arg;
pthread_join(id, NULL);
int i = 0;
for(i = 2; i < 100; ++i)
{
int j = 2;
for(; j <= i/2; ++j)
{
if(i % j == 0)
{
break;
}
}
if(j > i/2)
{
printf("%d ", i);
}
}
printf("\n");
}
void *fun2(void *arg)
{
int arr[] = {23,12,43,14,76,34,55,93,64,6};
int len = sizeof(arr)/sizeof(arr[0]);
int i = 0, j = 0;
for(; i < len - 1; ++i)
{
int min = i;
for(j = i + 1; j < len; ++j)
{
if(arr[j] < arr[min])
{
min = j;
}
}
int c = arr[min];
arr[min] = arr[i];
arr[i] = c;
}
for(i = 0; i < len; ++i)
{
sleep(1);
printf("%d ", arr[i]);
fflush(stdout);
}
printf("\n");
pthread_exit("sort over");
}
void main()
{
pthread_t id1,id2;
int res = pthread_create(&id1, NULL, fun1, (void*)&id2);
assert(res == 0);
res = pthread_create(&id2, NULL, fun2, NULL);
assert(res == 0);
char *p = NULL;
pthread_join(id1, NULL);
//pthread_join(id2,(void**)&p);
//printf("%s\n", p);
printf("main end\n");
}