c/c++ 多线程入门(一)

linux下多线程的编程基本属于即开即用的情况,在这里主要介绍win下的多线程编程,都在平台API中。

基本概念

什么是线程?

首先线程是包含在进程内。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务,线程之间资源是共享的

多线程的优势?

如果只有一个线程,那么任务就是顺序执行的,你必须等待前面的任务完成,才能执行下一个任务。引入多线程则可以在你执行某个任务的过程中,执行其他任务。所以在耗时多任务中,应用非常广泛。

换种表述

线程在Unix系统下,通常被称为轻量级的进程,线程虽然不是进程,但却可以看作是Unix进程的表亲,同一进程中的多条线程将共享该进程中的全部系统资源,如虚拟地址空间文件描述符信号处理等等。但同一进程中的多个线程有各自的调用栈(call stack),自己的寄存器环境(register context),自己的线程本地存储(thread-local storage)。 一个进程可以有很多线程,每条线程并行执行不同的任务。

线程可以提高应用程序在多核环境下处理诸如文件I/O或者socket I/O等会产生堵塞的情况的表现性能。在Unix系统中,一个进程包含很多东西,包括可执行程序以及一大堆的诸如文件描述符地址空间等资源。在很多情况下,完成相关任务的不同代码间需要交换数据。如果采用多进程的方式,那么通信就需要在用户空间内核空间进行频繁的切换,开销很大。但是如果使用多线程的方式,因为可以使用共享的全局变量,所以线程间的通信(数据交换)变得非常高效

代码介绍

pthread_create

简述:创建线程。

第一个参数 tidp 为 指向线程标识符指针。保存的是线程id。

第二个参数 attr 一个不透明的属性对象,可以被用来设置线程属性。您可以指定线程属性对象,也可以使用默认值 NULL。

第三个参数 start_rtn 线程运行函数起始地址,即线程函数名。

最后一个参数 arg 运行函数的参数。它必须通过把引用作为指针强制转换为 void 类型进行传递。如果没有传递参数,则使用 NULL。

int pthread_create(pthread_t *tidp,const pthread_attr_t *attr, 
                   (void*)(*start_rtn)(void*),void *arg);

创建线程成功时,函数返回 0,若返回值不为 0 则说明创建线程失败。

pthread_exit

简述:调用这个函数可以显示得退出线程
pthread_exit 用于显式地退出一个线程。通常情况下,pthread_exit() 函数是在线程完成工作后无需继续存在时被调用。

void  pthread_exit(void  *retval);

pthread_join

简述:用来等待一个线程的结束,使一个线程等待另一个线程结束,主要于线程间同步的操作。不使用的话,该线程结束后并不会释放其内存空间,这会导致该线程变成了“僵尸线程”。

thread: 线程标识符,即线程ID,标识唯一线程。

retval: 用户定义的指针

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

pthread_detach

简述:主线程与子线程分离,子线程结束后,资源自动回收。pthread_join()函数的替代函数。如果tid尚未终止,pthread_detach()不会终止该线程。

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

Sleep函数

功能: 执行挂起一段时间,也就是等待一段时间在继续执行

用法:Sleep(时间)

头文件

  • Windows下为–> windows.h

  • Linux 下为 --> unistd.h

注意
(1)Sleep是区分大小写的,有的编译器是大写,有的是小写。
(2)Sleep括号里的时间,在windows下是已毫秒为单位,而Linux是以为单位

示例

#include <stdio.h>   
#include <pthread.h>  
#include <time.h>
#include <windows.h>//使用Sleep的头

int g_number = 0;

#define MAX_COUNT 10000

//pthread_mutex_t mut;

void *counter3(void* args) {

	int i = 1;
	while (i <= MAX_COUNT / 4) {
		//pthread_mutex_lock(&mut);
		g_number++;
		//pthread_mutex_unlock(&mut);
		printf("hi,i am pthread 3, my g_number is [%d]\n", g_number);
		Sleep(1);// 单位ms,程序暂停一断时间再执行,这段时间内不会消耗CPU
		i++;
	}
}

void *counter4(void* args) {
	int j = 1;
	while (j <= MAX_COUNT / 4) {
		//pthread_mutex_lock(&mut);
		g_number++;
		//pthread_mutex_unlock(&mut);
		printf("hi,i am pthread 4, my g_number is [%d]\n", g_number);
		Sleep(1);
		j++;
	}
}

int main() {
	//pthread_mutex_init(&mut, NULL);
	pthread_t t3;
	pthread_t t4;
	pthread_create(&t3, NULL, counter3, NULL);
	pthread_create(&t4, NULL, counter4, NULL);

	getchar();
	return 0;
}

输出
在这里插入图片描述
1、为什么少加了几个?根本原因是什么?

2、怎么通过更改 代码的判断条件或者sleep或者pthread_mutex_lock 去解决这个问题,让他输出为5000?哪种方法更好?

3、写个for循环5000次+sleep(1)看看耗时多少,对比多线程和单线程时间的差异。

详见下篇。

转载自 https://zhuanlan.zhihu.com/p/97418361

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值