基本知识,无参数Thread和带参数的Thread

Thread类的参数就是参数指针,可以传入一个无参的函数。

如果要传入带参数的函数,先new一个ParameterizedThreadStart委托实例,带参数的函数名作为它的参数。带参数的函数必须且只能有一个object参数。参考下面的

ConterWithParam(object param)

static int iCnt = ;
static readonly int N = ; static void Main(string[] args)
{
Thread[] thrs = new Thread[N];
for (int i = ; i < N; i++)
{
thrs[i] = new Thread(Counter);
thrs[i].Start();
}
for (int i = ; i < N; i++)
{
thrs[i].Join();
}
Console.WriteLine(iCnt); iCnt = ; ParameterizedThreadStart[] thrsp = new ParameterizedThreadStart[N];
object param = ;
for (int i = ; i < N; i++)
{
thrsp[i] = new ParameterizedThreadStart(ConterWithParam);
thrs[i] = new Thread(thrsp[i]);
thrs[i].Start(param);
}
for (int i = ; i < N; i++)
{
//当NewThread调用Join方法的时候,MainThread就被停止执行,直到NewThread线程执行完毕
thrs[i].Join();
}
Console.WriteLine(iCnt);
} static void Counter()
{
Thread.Sleep();
iCnt++;
//Console.WriteLine("finish iCnt++,now iCnt is " + iCnt);
} static void ConterWithParam(object param)
{
Thread.Sleep();
int i = (int)param;
iCnt += i;
//Console.WriteLine("finish iCnt+"+i+",now iCnt is " + iCnt);
}

该例子输出结果

2)互斥信号灯mutex

第一节的结果是不是有点奇怪。明明加了10000次,结果却是9550.

带参数的那个例子,一次加2,加10000次,应该是20000才对。结果却是19678.

这是因为对全局变量的访问iCnt出现了冲突。比如两个线程同时取到了iCnt=0时的值,同时执行了i++,那么iCnt的最后状态肯定是1,而不是会2。为了让iCnt得到正确的值。

我们引入互斥信号灯。

static int iCnt = ;
static readonly int N = ;
static Mutex mut = new Mutex(); static void Main(string[] args)
{
Thread[] thrs = new Thread[N];
for (int i = ; i < N; i++)
{
thrs[i] = new Thread(Counter);
thrs[i].Start();
}
for (int i = ; i < N; i++)
{
thrs[i].Join();
}
Console.WriteLine(iCnt); iCnt = ; ParameterizedThreadStart[] thrsp = new ParameterizedThreadStart[N];
object param = ;
for (int i = ; i < N; i++)
{
thrsp[i] = new ParameterizedThreadStart(ConterWithParam);
thrs[i] = new Thread(thrsp[i]);
thrs[i].Start(param);
}
for (int i = ; i < N; i++)
{
//当NewThread调用Join方法的时候,MainThread就被停止执行,直到NewThread线程执行完毕
thrs[i].Join();
}
Console.WriteLine(iCnt);
} static void Counter()
{
Thread.Sleep();
//锁
mut.WaitOne();
iCnt++;
//释放
mut.ReleaseMutex();
//Console.WriteLine("finish iCnt++,now iCnt is " + iCnt);
} static void ConterWithParam(object param)
{
Thread.Sleep();
//锁住
mut.WaitOne();
int i = (int)param;
iCnt += i;
//释放
mut.ReleaseMutex();
//Console.WriteLine("finish iCnt+"+i+",now iCnt is " + iCnt);
}

本次执行结果

3) 同步信号灯Semaphore

用最经典的生产者-消费者来解释。

static Semaphore sem = new Semaphore(, );
static Semaphore sem2 = new Semaphore(, ); static void Main(string[] args)
{
Console.WriteLine("消费者等生产者生产一个item");
Thread thConsumer = new Thread(Consume);
thConsumer.Start();
Thread thProductor = new Thread(Product);
thProductor.Start(); thConsumer.Join();
thProductor.Join();
Console.WriteLine("............................."); Console.WriteLine("多并发的例子.....");
for (int i = ; i < ; i++)
{
Thread t1 = new Thread(Consume2);
t1.Start();
Thread t2 = new Thread(Product2);
t2.Start();
}//end for } static void Product()
{
Thread.Sleep();
Console.WriteLine("Product an item...");
sem.Release();
} static void Consume()
{
Thread.Sleep();
Console.WriteLine("Consumer is waiting an item...");
sem.WaitOne();
Console.WriteLine("Consumer get an item...");
} static void Product2()
{
Thread.Sleep();
Console.WriteLine("Product an item...");
sem2.Release();
} static void Consume2()
{
Thread.Sleep();
Console.WriteLine("Consumer is waiting an item...");
sem2.WaitOne();
Console.WriteLine("Consumer get an item...");
}

C# 语言的多线程编程,完全是本科OS里的知识的更多相关文章

  1. Rust语言的多线程编程

    我写这篇短文的时候,正值Rust1.0发布不久,严格来说这是一门兼具C语言的执行效率和Java的开发效率的强大语言,它的所有权机制竟然让你无法写出线程不安全的代码,它是一门可以用来写操作系统的系统级语 ...

  2. C语言 之 多线程编程

    一.基础知识 计算机的核心是CPU,承担了所有的计算任务. 操作系统是计算机的管理者,负责任务的调度.资源的分配和管理,统领整个计算机硬件. 应用程序则是具有某种功能的程序,程序是运行于操作系统之上的 ...

  3. linux下c语言的多线程编程

    我们在写linux的服务的时候,经常会用到linux的多线程技术以提高程序性能 多线程的一些小知识: 一个应用程序可以启动若干个线程. 线程(Lightweight Process,LWP),是程序执 ...

  4. java多线程编程(1) 线程的基本知识

    在前面研究过多线程与进程的区别. 这里在稍微总结一下: 进程:程序动态的一次执行过程. 线程:可以只是程序员的一部分的执行过程 每个进程有多个线程组成,在java程序中,至少两个线程一个是垃圾回收线程 ...

  5. linux下C语言多线程编程实例

    用一个实例.来学习linux下C语言多线程编程实例. 代码目的:通过创建两个线程来实现对一个数的递加.代码: //包含的头文件 #include <pthread.h> #include ...

  6. C语言中的多线程编程

    很久很久以前,我对C语言的了解并不是很多,我最早听说多线程编程是用Java,其实C语言也有多线程编程,而且更为简单.方便.强大.下面就让我们简单领略一下Unix C语言环境下的多线程编程吧! 下面先看 ...

  7. C语言多线程编程

    HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, DWORD dwStackSize, LPTHREAD_START_ROUT ...

  8. C语言使用pthread多线程编程(windows系统)二

    我们进行多线程编程,可以有多种选择,可以使用WindowsAPI,如果你在使用GTK,也可以使用GTK实现了的线程库,如果你想让你的程序有更多的移植性你最好是选择POSIX中的Pthread函数库,我 ...

  9. Linux C语言多线程编程实例解析

    Linux系统下的多线程遵循POSIX线程接口,称为 pthread.编写Linux下的多线程程序,需要使用头文件pthread.h,连接时需要使用库libpthread.a.顺便说一下,Linux ...

随机推荐

  1. Maven: NoClassDefFoundError: org/codehaus/plexus/classworlds/launcher/Launcher

    为了和团队开发环境保持一致,须要 在Ubuntu上安装maven2.2.1,引文我之前已经用apt-get命令安装了3.3的maven.在运行maven命令时报错: Maven: NoClassDef ...

  2. mybatis generator插件开发

    mybatis现在普遍使用的每一个人DAO框架.mybatis generator它可以基于数据库中的表结构,生成自己主动mybatis代码和配置文件,方便使用,当然,实际的使用过程中.generat ...

  3. malloc实现原理

    记得早一段时间,看到一本书上写过delete的一个..今天突然找啦一下资料: malloc()是C语言中动态存储管理 的一组标准库函数之中的一个.其作用是在内存的动态存储区中分配一个长度为size的连 ...

  4. CSS小记(持续更新......)

    1 内联元素和块级元素的区别以及display的三种属性区别 在说起display属性之前,就必须先说说什么是文档流,以及文档流中的内敛元素和块级元素又是指什么? 一直觉得理解了文档流的概念,一堆CS ...

  5. Git & Github 一页简明笔记(转)main

    由于小组工程需要使用git&github的版本控制来协作,但我对其使用并不熟悉,特此写篇一页的笔记放在手边,备随时查阅. 使用方法:常用命令供随时查阅,其余内容供新手了解. 0. 常用命令一览 ...

  6. java 获取系统变量(环境变量和环境变量)

    前言 环境变量这个概念不陌生, 就是操作系统的环境变量. 系统变量就是java本身维护的变量. 通过 System.getProperty 的方式获取. 对于不同的操作系统来说. 环境变量的处理可能会 ...

  7. 面向对象三大特征之继承(extends)——Java笔记(六)

    继承:            从一般到特殊的关系,是一种拓展关系,子类对象是父类的一种,也可称为”is a“的关系 泛化:         把子类里的共性抽取到父类里的来的过程 特化:         ...

  8. Visual Studio 2010/2013 查看DLL接口(函数)

    1. “应用程序" Visual Studio 2010/2013 的Visual Studio Tools文件夹中打开Visual Studio Command Prompt 命令提示窗口 ...

  9. js中位运算的运用

    原文:js中位运算的运用 我们可能很少在编程中用位运算,如果没深入学习,可能也很难理解.平时的数值运算,其实是要先转换成二进制再进行运算的,而位运算就是直接进行二进制运算,所以位运算的执行效率肯定是更 ...

  10. Meteor入门

    转载Meteor入门介绍   Meteor是什么 基于nodejs的实时web APP开发框架. Meteor能带来什么 简单的说,你可以用js搞定客户端.服务端的开发.另外,客户端.服务端的界限被极 ...