多线程和多进程(2019/9/11每天学习10个博客系列)

一.以操作系统的角度诉说线程和进程-----------
原文连接:http://blog.csdn.net/luoweifu/article/details/46595285
大部分操作系统的任务调度是采用时间片轮转的抢占调度方式,任务执行的一小段时间叫做时间片。进程是一个具有一定独立功能的程序在一个数据集上的一次动态执行过程,是操作系统运行资源分配和调度的一个独立单元,是应用程序运行的载体。
1.程序:用于描述进程要完成的功能,是控制进程执行的指令集
2.数据集合:是程序在执行时需要的数据和工作区
3.程序控制块:(PCB):包含进程的描述信息和控制信息,是进程存在的唯一标识
**线程是程序执行中的一个单一的顺序控制流程,是程序执行的流的最小单元,是处理调度器和分派的基本单元。
1.线程ID
2.当前指令指针PC
3.寄存器
4.堆栈

进程:内存空间和线程组成
优先级调度:
1.把频繁等待的线程称之为IO密集型线程,把很少等待的线程称之为CPU密集型线程。
为了避免线程饿死,调度系统通常会逐步提升那些等待了很久而得不到执行的程序的优先级
线程安全与锁
所谓同步就是一个线程在一个时刻访问一个数据,使用锁机制
二元信号量是一种简单的锁两种状态:占用和非占用。适合唯一一个线程独占访问的资源
多元信号量允许线程访问同一个资源,多元信号量简称信号量
一个初始值位N的信号量允许N个线程并发访问,程序访问资源时首先获取信号量锁,并:
1.将信号量的值减1
2.如果信号量的值小于0,则进入等待状态,否则继续执行
访问资源结束后,线程释放信号量锁,进行如下操作
互坼量
与二元信号类似,哪个线程获取就由哪个线程释放
临界量更加严格,作用范围仅局限于本进程
读写锁允许多个线程同时对同一个数据进行读操作,而只允许一个线程进行写操作。读写锁的状态:自由,共享,独占。
Windows中线程相关的操作和方法
CreateThread用于创建一个线程其函数原型为:
HANDLE WINAPI CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAtttibutes;//线程安全相关属性,常置为NULL
SIZE_T dwStackSize,//新线程的初始化栈的大小,可以设置为0
LPTHREAD_START_ROUTINE lpStartAddress//被线程执行的回调函数,也称为线程函数
其中指针ipThreadAttibutes指针指向结构体,确定返回的句柄可以被子线程继承不。对此我们需要对句柄有一个大概认识:
windows之所以要设立句柄,根本原因源自内存管理机制的虚拟地址问题,系统用句柄来记载数据地址的变更,是一种指向指针的指针
------对于句柄讲的很不错非常不错的大神博客:文大侠-------https://blog.csdn.net/wenzhou1219/article/details/17659485
**为什么要用#ifdef … #endif
在C语言中,我们通常会在头文件里面声明外部使用的宏定义,函数声明以及全局变量定义之类的,包含头文件即可。但是如果多个c文件同时包含了同一个头文件,可能出现宏,变量,重复定义,导致编译不通过。
在头文件中1使用:
#ifndef _KEYBOARD_H
#define _KEYBOARD_H

#endif
通过这种方法,当第一次使用这个头文件的c文件,编译查看是否定义_KEYBOARD_H,第一次肯定没有,所以它就定义了头文件里面的相关宏及变量
第二次使用就检查不会重复定义
比较有面视意义的连接:https://blog.csdn.net/newjerry/article/details/4383701
回调函数
为什么我们要把函数作为参数来调用呢,直接在函数体调用不行吗,以不变应万变,形参是不变的,实参是变化的,为了使排序算法能够适应不同类型的数据,并且按各种要求进行排序,把排序算法做成一个模板(标准模板库STL),并且把判断两个数据之间的大小这个任务(函数)当成一个参数放在排序算法这个函数的参数列表里,这个判断大小的函数就是一个回调函数。比如我们要给某个vector容器里面的单词进行排序,我们声明一个排序算法:
void stable_sort(vector::iterator iterBegin,vector::iterator iterEnd,
bool (*isShorter)(const string &,const string &);
其中前面两个参数普通参数,即迭代器用于标记vector容器里面元素的位置,而第十三个参数isShorter就是回调函数。
转载连接:https://blog.csdn.net/u014078216/article/details/49717405
IpStartAddress:指向一个函数指针,该函数将被线程调用执行,因此该函数也成为线程函数,是线程执行的起始地址,线程函数是一个回调函数,由操作系统在线程中调用。
线程函数的原型为DWORD WINAPI ThreadProc(LPVOID lpParameter);//lpParameter是传入的参数,是一个空指针,传入线程函数(ThreadProc)的参数,不需传递参数为NULL
dwCreationFlags:控制线程创建的标志,有三个类型 0:线程创建后立即执行线程
CREATE_SUSPENDED:线程创建后进入就绪状态,直到线程被唤醒时才调用
dwStackSize
会设为系统预留的值
BOOL WINAPI CloseHandle(HANDLE hobject);
可用这个函数关闭创建的线程句柄
1、首先,由于MFC默认需要使用stdafx.h,所以需要在核心源代码中的每个cpp文件开头添加一行代码:#include "stdafx.h",这样会导致Linux和Windows平台所使用的核心函数库源代码的不一致。 解决这一问题的方法是:在VC++ 6.0中,Project->Settings对话框,C/C++标签页,Category选择“Precompiled Headers”,然后在下面勾选“Not using precompiled headers”。这样设置之后就不需要stdafx.h这个头文件了! 2、这样设置之后再编译工程,又导致另外的错误:nafxcwd.lib(afxmem.obj) :error LNK2005: "void * __cdecl operator new(unsigned int)"(??2@YAPAXI@Z) already defined in LIBCMTD.lib(new.obj) 解决方案是:在VC++ 6.0中,Project->Settings对话框,左侧选择“Win32 Debug”,然后在Link标签页,Category选择input,然后在Object/library modules框中输入“Nafxcwd.lib Libcmtd.lib”,在Ignore libraries框中输入“Nafxcwd.lib,Libcmtd.lib”。请注意此处分隔符的差异。 然后左侧选择“Win32 Release”,然后在Link标签页,Category选择input,然后在Object/library modules框中输入“nafxcwd.lib libcmtd.lib”,在Ignore libraries框中输入“nafxcwd.lib,libcmtd.lib”。请注意此处分隔符的差异,并请注意Release版本和Debug版本设置的差异,关键在于:库文件名首字母的大小写!

memset()的效率以及源码分析
void *memset(void *s,int ch,size_t n);
将s所指向的某一块内存中的每一个字节的内容全部设置为ch指定的ASCII值,块的大小由第三个参数指定,这个函数通常为新申请的内存做初始化工作。
void *(memset)(void *s,int c,size_t n)
{
const unsigned char uc = c;
unsigned char *su;
for(su = s;0<n;++su;–n)
*su =uc;
return s;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值