第三季-第20课-多线程程序设计

第20课-多线程程序设计

 

20.1 核心概念

多人垒墙的故事:计划建立一个高墙,现在只有一个工人。为了加快进度,我们可以雇用多个工人。我们假设已经雇用了多个工人,而且每个工人都带有一个吃饭的锅,但是,实际的工作中,这些工人是可以共用一个锅的。

这就好比我们的一个工作,为了加快进度,我们启用了多进程的工作方式。实际中我们用的fork()函数来生成,但是,这种方式是有弊端的。用该种方式生成的子进程将父进程的资源(数据段和代码段都复制了),这就造成了资源的浪费,也增加了程序运行的时间。为了避免这种方式,我们提出了线程的概念。线程相对于多进程来说具有以下的优点:

l  线程就是“轻量级”的进程。

l  线程与创建它的进程共享代码段和数据段。

l  线程拥有自己独立的栈。

20.2 函数学习

1. 创建线程

(1) 函数名

pthread_create

(2) 函数原型

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start routine) (void *),void *arg);

(3) 函数功能

创建新的线程。creat a new thread,starts a new thread in the calling process

(4) 包含的头文件

#include<pthread.h>

特比注意:我们只要使用这一个函数,我们在编译的时候就要使用 gcc -lpthread这个命令。

(5) 返回值

成功:0

失败:错误的编码

(6) 参数说明

thread:新创建的线程id

attr:待创建线程的属性,以后看到attr就要想到属性。

start routine:线程的入口函数

arg:线程入口函数的参数,可以为空。

2. 等待线程

(1) 函数名

pthread_join

当进程结束的时候,进程创建的线程就会结束(子进程不会结束)。当进程A结束时候,它是不能退出的,我们要等待着它的线程也结束才可以,所以我们需要这里的函数。

(2) 函数原型

int pthread_join(pthread_t thread, void **retval);

(3) 函数功能

等待线程的结束waits for the thread specified by thread to terminate

(4) 包含的头文件

#include<pthread.h>

(5) 返回值

成功:0

失败:错误编号

(6) 参数说明

thread:要等待结束的线程id;

retval:保存线程退出时的状态,一般是空(不保存)。

3. 终止线程

(1) 函数名

pthread_exit,只会退出调用的单个线程。

不能用exit()这个函数,我们要用这个函数,会导致这个进程都退出的。

(2) 函数原型

void pthread_exit(void *retval);

(3) 函数功能

结束进程。This function terminates the calling thread and returns a value via retval that (if the thread is joinable) is available to another thread in the same process that calls pthread_join. 

(4) 包含的头文件

#include<pthread.h>

(5) 返回值

(6) 参数说明

retval:保存返回值。

20.3 线程互斥

在实际应用中,多个线程往往会访问同一数据或资源,为了避免线程之间的相互影响,需要引入线程互斥机制,而互斥锁(mutex)就是互斥机制中的一种。多进程用的是信号量。

1. 互斥锁初始化

(1) 函数名

pthread_mutex_init

(2) 函数原型

int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexatter_t *restrict attr);

(3) 函数功能

初始化互斥锁。(shall initialize the mutex referenced by mutex with attributes specified by attr.)

(4) 包含的头文件

#include<pthread.h>

(5) 返回值

成功:0

失败:错误的编码

(6) 参数说明

mutex:初始化的互斥锁的指针

attr:属性,为NULL表示默认

2. 获取互斥锁

(1)函数名

pthread_mutex_lock

(2)函数原型

int pthread_mutex_lock(pthread_mutex_t *mutex);

(3)函数功能

初始化互斥锁。(The mutex object referenced by mutex shall be locked by calling pthread mutex lock().)

(4)包含的头文件

#include<pthread.h>

(5)返回值

成功:0

失败:错误的编码(error number)

(6)参数说明

mutex:指定互斥锁的指针

3. 释放互斥锁

(1)函数名

pthread_mutex_unlock

(2)函数原型

int pthread_mutex_unlock(pthread_mutex_t *mutex);

(3)函数功能

释放化互斥锁。

(4)包含的头文件

#include<pthread.h>

(5)返回值

成功:0

失败:错误的编码(error number)

(6)参数说明

mutex:指定互斥锁的指针

20.4 综合实例

pthread.c

#include<pthread.h>

#include<stdio.h>

int number = 0;

pthread_mutex_t mut;

pthread_t thread[2];

void * worker1()

{

         int i = 0;

         printf("Iam worker1! ");

         for(i=0;i<10;i++)

         {

                  pthread_mutex_lock(&mut);  //锁

                  number++;

                  pthread_mutex_unlock(&mut); // 解锁

                  printf("worker1 number is %d ",number);

                  sleep(1);

         }

         pthread_exit(NULL);

void * worker2()

{

         int i = 0;

         printf("Iam worker2! ");

         for(i=0;i<10;i++)

         {

pthread_mutex_lock(&mut);  //锁

                  number++;

                  pthread_mutex_unlock(&mut); // 解锁

                  printf("worker2 number is %d ",number);

                  sleep(1);

         }

         pthread_exit(NULL);

//假设墙有20层

int main()

{

         pthread_mutex_init(&mut, NULL);

         //锁的初始化

         //创建工人1线程

         pthread_create(&thread[0], NULL, worker1,NULL);

         //创建工人2线程

         pthread_create(&thread[1], NULL, worker2,NULL);

         //等待工人1线程的结束

         pthread_join(thread[0], NULL);

         //等待工人2线程的结束

         pthread_join(thread[1], NULL);

         return 0;

}

运行结果:I am worker1!

          I am worker2!

          worker1 number is 1

          worker2 number is 2

          worker1 number is 3

          worker2 number is 4

          worker1 number is 5

          worker2 number is 6

          worker1 number is 7

          worker2 number is 8

          worker1 number is 9

          worker2 number is 10

          worker1 number is 11

          worker2 number is 12

          worker1 number is 13

          worker2number is 14

          worker1 number is 15

          worker2 number is 16

          worker1 number is 17

          worker2 number is 18

          worker1 number is 19

          worker2 number is 20

         

原文地址:https://www.cnblogs.com/free-1122/p/11352840.html