C#多线程参数传递

C#多线程参数传递
C#多线程参数传递

C#多线程参数传递

在多线程或单线程任务中,让线程带传入参数一直是个麻烦的问题,通常有种方法就是以类,对像的变量来传参数,这种方法理解上很简单不过在某些场合使用很麻烦,这里就不介绍了,我们主要介绍一种.NET2.0中新增加的带参数运行线程的方法,示例程序如下:

ParameterizedThreadStart ParStart = new ParameterizedThreadStart(ThreadMethod); Thread myThread = new Thread(ParStart);

object o = “hello”;

myThread.Start(o);

ThreadMethod如下:

public void ThreadMethod(object ParObject)

{

//程序代码

}

如果是多参数的话可以以数组或动态列表等方式装相入 object,然后使用时拆箱即可

这样是不是简单多了哈,,, ———————————————————————————–

[转]个人认为,还是为线程创建一个单独的类,在类的初始化函数里头为类里头的变量赋值,来达到传入参数比较简单。下面有些方法是有问题的,不过我已经达到了目的就懒得去排错了,哪位朋友看出问题了提醒一下啊。呵呵…

方法一:

在VS2003中,也不能直接访问,参看

一般来说,直接在子线程中对窗体上的控件操作是会出现异常,这是由于子线程和运行窗体的线程是不同的空间,因此想要在子线程来操作窗体上的控件,是不可能简单的通过控件对象名来操作,但不是说不能进行操作,微软提供了Invoke的方法,其作用就是让子线程告诉窗体线程来完成相应的控件操作。

现在用一个用线程控制的进程条来说明,大致的步骤如下:

1.创建Invoke函数,大致如下:

///

/// Delegate function be invoked by main thread

///

private void InvokeFun()

{

if(prgBar.Value< 100)

prgBar.Value = prgBar.Value + 1;

}

2.子线程入口函数:

///

/// Thread function interface

///

private void ThreadFun()

{

// Create invoke method by specific function

MethodInvoker mi = new MethodInvoker(this.InvokeFun);

for(int i=0; i<100; i++)

{

this.BeginInvoke(mi);

Thread.Sleep(100);

}

}

3.创建子线程:

Thread thdProcess = new Thread(new ThreadStart(ThreadFun));

thdProcess.Start();

备注:

using System.Threading;

private System.Windows.Forms.ProgressBar prgBar;

方法二:

加入该句:Control.CheckForIllegalCrossThreadCalls = False 取消线线程安全保护模式!

方法三:带参数

使用类、类的方法或类的属性都可以向线程传递参数:

public class UrlDownloader

{

string url;

public UrlDownloader (string url)

{

this.url = url;

}

public void Download()

{

WebClient wc = new WebClient();

Console.WriteLine(“Downloading ” + url);

byte[] buffer = wc.DownloadData (url);

string download = Encoding.ASCII.GetString(buffer);

Console.WriteLine(download);

Console.WriteLine(“Download successful.”);

//这里你可以将download进行保存等处理……

}

}

[... 在另一个类中使用它们...]

UrlDownloader downloader = new UrlDownloader (yourUrl);

new Thread (new ThreadStart (downloader.Download)).Start();

注意参数是如何传递的。

方法四:带参数

ThreadStart starter = delegate { Download(yourUrl); };

new Thread(starter).Start();

//使用线程?

WaitCallback callback = delegate (object state) { Download ((string)state); }; ThreadPool.QueueUserWorkItem (callback, yourUrl);

方法五:带参数

Thread t = new Thread (new ParameterizedThreadStart(DownloadUrl));

t.Start (myUrl);

static void DownloadUrl(object url)

{

// ….

—————————————————————————-

—————————————————————————-

C#线程调用带参数的方法

之前做了一个小的应用程序,用的是c#语言,在做的过程中遇到了一个困难,就是不如调用带参数的线程,经过查找网上的资料,找到了简单的解决方案。

在以前的学习中,我们经常碰到的是没有带参数的线程,所以当遇到必须用到参数的线程时就会手足无措,现在我们用的这种解决问题的方法,实际上的原理是:将线程执行的方法和参数都封装到一个类里面。通过实例化该类,方法就可以调用属性来实现间接的类型安全地传递参数。看如下代码:

using System;

using System.Threading;

//ThreadWithState 类里包含了将要执行的任务以及执行任务的方法

public class ThreadWithState {

//要用到的属性,也就是我们要传递的参数

private string boilerplate;

private int value;

//包含参数的构造函数

public ThreadWithState(string text, int number)

{

boilerplate = text;

value = number;

}

//要丢给线程执行的方法,本处无返回类型就是为了能让ThreadStart来调用

public void ThreadProc()

{

//这里就是要执行的任务,本处只显示一下传入的参数

Console.WriteLine(boilerplate, value);

}

}

---------------分隔线---------------

//用来调用上面方法的类,是本例执行的入口

public class Example {

public static void Main()

//实例化ThreadWithState类,为线程提供参数

ThreadWithState tws = new ThreadWithState(

“This report displays the number {0}.”, 42);

// 创建执行任务的线程,并执行

Thread t = new Thread(new ThreadStart(tws.ThreadProc));

t.Start();

Console.WriteLine(“Main thread does some work, then waits.”); t.Join();

Console.WriteLine(

“Independent task has completed; main thread ends.”);

}

}

从上面的例子就能很清楚的得到我们想要的结果,注意这句代码的用法:Thread t = new Thread(new ThreadStart(tws.ThreadProc));

4:一个经典的多线程同步问题汇总

一个经典的多线程同步问题 程序描述: 主线程启动10个子线程并将表示子线程序号的变量地址作为参数传递给子线程。子线程接收参数 -> sleep(50) -> 全局变量++ -> sleep(0) -> 输出参数和全局变量。 要求: 1.子线程输出的线程序号不能重复。 2.全局变量的输出必须递增。 下面画了个简单的示意图: 分析下这个问题的考察点,主要考察点有二个: 1.主线程创建子线程并传入一个指向变量地址的指针作参数,由于线程启动须要花费一定的时间,所以在子线程根据这个指针访问并保存数据前,主线程应等待子线程保存完毕后才能改动该参数并启动下一个线程。这涉及到主线程与子线程之间的同步。 2.子线程之间会互斥的改动和输出全局变量。要求全局变量的输出必须递增。这涉及到各子线程间的互斥。 下面列出这个程序的基本框架,可以在此代码基础上进行修改和验证。 //经典线程同步互斥问题 #include #include #include long g_nNum; //全局资源 unsigned int__stdcall Fun(void *pPM); //线程函数 const int THREAD_NUM = 10; //子线程个数 int main() { g_nNum = 0;

HANDLE handle[THREAD_NUM]; int i = 0; while (i < THREAD_NUM) { handle[i] = (HANDLE)_beginthreadex(NULL, 0, Fun, &i, 0, NULL); i++;//等子线程接收到参数时主线程可能改变了这个i的值} //保证子线程已全部运行结束 WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE); return 0; } unsigned int__stdcall Fun(void *pPM) { //由于创建线程是要一定的开销的,所以新线程并不能第一时间执行到这来int nThreadNum = *(int *)pPM; //子线程获取参数 Sleep(50);//some work should to do g_nNum++; //处理全局资源 Sleep(0);//some work should to do printf("线程编号为%d 全局资源值为%d\n", nThreadNum, g_nNum); return 0; } 运行结果:

C#多线程函数如何传参数和返回值

C#多线程函数如何传参数和返回值 提起多线程,不得不提起委托(delegates)这个概念. 我理解的委托就是具有同样参数和返回值的函数的集合. 比如 public delegate void MyDelegate(int arg); 就是这种形式的函数 void Myfuntion(int i); 的集合. 如何将一个函数加入委托的集合? MyDelegate dele = new MyDelegate(Myfuntion1); 再增加一个 dele += new MyDelegate(Myfuntion2); ... 委托函数 dele 就是具有整数参数和空返回值的函数 Myfuntion1,2的集合. 调用这个委托函数 dele(1); 就是逐个调用 Myfuntion1,2,... 一般线程函数的声明和启动 Thread t = new Thread(new ThreadStart(MyFunction)); t.Start(); 正是调用了没有参数和返回值的委托函数 ThreadStart 其中的参数MyFunction 是这个委托函数中的一员. 很明显这样无法传参数和返回值,那我们该怎么办? 答案就在委托的BeginInvoke() 方法上, BeginInvoke() 也是(异步)启动一个新线程. 例如 MyDelegate dele = new MyDelegate (MyFunction); dele.BeginInvoke(10,"abcd"); void MyFunction(int count, string str); 可以实现参数的传递. 如何收集线程函数的返回值? 与BeginInvoke 对应有个 EndInvoke 方法,而且运行完毕返回 IAsyncResult 类型的返回值.这样我们可以这样收集线程函数的返回值 MyDelegate dele = new MyDelegate (MyFunction); IAsyncResult ref = dele.BeginInvoke(10,"abcd"); ...

基于多线程的制造数据分析和可视化

2007年第24卷第10期微电子学与计算机105 4实例 焊膏印刷是SMT生产过程中的主要工序之一.下面以实现焊膏印刷的焊膏印刷机为例.对上述的原理和过程进行验证。 焊膏印刷机是通过在印刷设备的PC机中插入符合开放标准GEM/SECSlI(通用设备模型)的主机通信卡来实现关键信息的采集。所采集的数据类型包括:前刮刀压力、前刮刀印刷速度、后刮刀压力、后刮刀印刷速度、刮刀正行程位置、刮刀负行程位置、温度值、湿度值等。 该系统首先进入用户登录界面:根据用户的不同权限等级.给与不同的操作许可。选择不同的设备、订单名称、工艺文件名称,开始生产后,焊膏印刷机能方便的实时显示界面。选择想要绘制盖—霄控制图的数据类型.即可绘制出该数据类型的盖—月控制图。如图4所示。 图4-_一R控制图显示界面 5结束语 由于采用了多线程、数据动态实时显示、多媒体定时器、夏—R控制图等技术,使程序实现了对多设备大数据量的实时数据采集、存储、绘制曲线,及时判断数据是否处于失控状态.缩短了延时时间。制造数据可视化程度达95%以上为车间的操作人员提供了随时了解设备运行情况的有效手段.在现实应用中具有广泛的实用价值。 当然.程序也存在一些不足。程序运行在WindowsXP操作系统下.多任务操作系统固有的任务切换:其他驱动程序的CPU时间的抢占;高优先级应用程序的执行:不确定的操作系统的作业任务分配规则等许多问题.都可以导致多媒体定时器定时的不准确。所以,要提高精度.可以考虑采用专门的硬件电路。通过软硬件相结合,以达到高精度的定时,提高应用程序的实用性。 参考文献: 【1】帅梅,王爱周,王广毙.基于Windows数控系统得多线程实现叨.机床与液压.2003 【2】吴丽娜.高槛阳.Wmdows2000/XP下通用实时采集的设计与实现Ⅱ1.计算机应用,2005 【3】肖建明,张向利.一种改进的时间片轮转调度算法田.计算机应用.2005 『41杨乐,王厚军,戴志坚.测试仪器中的动态波形绘制技术叨.仪器仪表学报,2006 『51曹祁,杜树旺.基于微机的压缩机数据采集方法研究与实现U1.仪器仪表学报.2006 【6】杨桂元.中心极限定理及其在统计分析中的应用【J】.管理工程学报.1998 作者简介: 王小婷女.(1969一)。研究方向为计算机工程与应用。 韩方女.研究生。研究方向为图形图像处理、制造过程仿真与优化。 (上接第101页) 网络系统中节点之间的相互作用导致了系统在宏观上表现出了复杂的整体行为.这些结果与已有的研究结果是相一致的日。 4结束语 文中建立了用于分析网络流量行为的一维元胞自动机模型.以节点发送数据分组的规则来描述在传输数据分组过程中节点间的相互影响以及自组织作用后使计算机网络分组传输系统表示出来的一种整体行为.模拟了网络系统发送数据分组随机的不确定状态。仿真结果说明该模型能较好地描述网络流量非拥塞相到拥塞相的变化过程。参考文献: 【1]WolframS.Cellularautomataandcomple6xity[M].RendingMA,Addison-Wesley,1994 【2】彭麟,谭惠丽,孔令江,等.开放性边界条件下双道元胞自动机变通流模型耦合效应研究Ⅱ].物理学报,2003,52(12):3007-3013 p]Ohira T,sa砌嘶凡PhasetransitioninEeom!tⅫltertlet?worktmmemodd田.P}-y8.Rev,1998:193-195 作者简介: 雷霆男.(1972-).博士研究生。讲师。研究方向为通信与信息系统、计算机网络。 余镇危 男.(1942一),教授。研究方向为计算机网络。

Winform多窗口或多线程传递数据的方法

前提:假设现在有两个窗口Form1和Form2, Form2是Form1的子窗口,现在需要通过Form2来改变Form1中的内容 效果: 方法一:使用Delegate(代理) 第一步:在Form2中定义代理并声明实例 第二步:在Form1中定义用来代理的函数 第三步:在Form1中生成Form2的实例并将代理赋值给Form2中的代理对象

第四步:在Form2中调用代理 总结:当Form2调用代理对象proEvent时实际上是在调用Form1中的Eventpro函数,由于Eventpro属于Form1,所以赋值成功。 方法二:使用自定义事件 第一步:自定义事件 第二步:在Form2中声明事件对象 第三步:在Form1中定义事件回调函数

第四步:创建Form2的对象实例,并将事件的回调函数添加到事件上(订阅事件) 第五步:在Form2中的按钮上触发事件 总结:当第五步事件被触发,事件对象Events会向所有订阅该事件的函数进行触发,而回调函数EventCallBack是Form1的成员,见第三步,所以数据传递成功。 利弊分析:第一种方法的优点显而易见,代理参数是可以自定义的,如:void EventPro(string Message),其缺点就是,每一个这样的跨窗口调用都需要在子窗口中定义一个代理对象,并在主窗口中赋值相应的函数。相对来说,我偏向于使用自定义事件,首先,不是所有学过winform的人都接触过这部分内容(高端大气上档次),其次,他可以实现一个函数向n个窗口传值,只要给事件添加订阅就可以了,frm.Events += new EventHandler(EventCallBack)。(方便)。另外,看过winform下层代

11线程池的使用

第11章线程池的使用 第8章讲述了如何使用让线程保持用户方式的机制来实现线程同步的方法。用户方式的同步机制的出色之处在于它的同步速度很快。如果关心线程的运行速度,那么应该了解一下用户方式的同步机制是否适用。 到目前为止,已经知道创建多线程应用程序是非常困难的。需要会面临两个大问题。一个是要对线程的创建和撤消进行管理,另一个是要对线程对资源的访问实施同步。为了对资源访问实施同步,Wi n d o w s提供了许多基本要素来帮助进行操作,如事件、信标、互斥对象和关键代码段等。这些基本要素的使用都非常方便。为了使操作变得更加方便,唯一的方法是让系统能够自动保护共享资源。不幸的是,在Wi n d o w s提供一种让人满意的保护方法之前,我们已经有了一种这样的方法。 在如何对线程的创建和撤消进行管理的问题上,人人都有自己的好主意。近年来,我自己创建了若干不同的线程池实现代码,每个实现代码都进行了很好的调整,以便适应特定环境的需要。M i c r o s o f t公司的Windows 2000提供了一些新的线程池函数,使得线程的创建、撤消和基本管理变得更加容易。这个新的通用线程池并不完全适合每一种环境,但是它常常可以适合你的需要,并且能够节省大量的程序开发时间。 新的线程池函数使你能够执行下列操作: ? 异步调用函数。 ? 按照规定的时间间隔调用函数。 ? 当单个内核对象变为已通知状态时调用函数。 ? 当异步I / O请求完成时调用函数。 为了完成这些操作,线程池由4个独立的部分组成。表11 - 1显示了这些组件并描述了控制其行为特性的规则。 表11-1 线程池的组件及其行为特性

并发危险:解决多线程代码中的 11 个常见的问题

并发危险:解决多线程代码中的11 个常见的问题 并发危险 解决多线程代码中的11 个常见的问题 Joe Duffy 目录 数据争用忘记同步粒度错误读写撕裂无锁定重新排序重新进入死锁锁保护戳记两步舞曲优先级反转实现安全性的模式不变性纯度隔离并发现象无处不在。服 务器端程序长久以来都必须负责处理基本并发编程模型,而随着多核处理器的日益普及,客户端程序也将需要执行一些任务。随着并发操作的不断增加,有关确保安 全的问题也浮现出来。也就是说,在面对大量逻辑并发操作和不断变化的物理硬件并行性程度时,程序必须继续保持同样级别的稳定性和可靠性。 与对应的顺序代码相比,正确设计的并发代码还必须遵循一些额外的规则。对内存的读写以及对共享资源的访问必须使用同步机制进行管制,以防发生冲突。另外,通常有必要对线程进行协调以协同完成某项工作。

这些附加要求所产生的直接结果是,可以从根本上确保线程始终保持一致并且保证其顺利向前推进。同步和协调对时间的依赖性很强,这就导致了它们具有不确定性,难于进行预测和测试。 这 些属性之所以让人觉得有些困难,只是因为人们的思路还未转变过来。没有可供学习的专门 API,也没有可进行复制和粘贴的代码段。实际上的确有一组基础概念需要您学习和适应。很可能随着时间的推移某些语言和库会隐藏一些概念,但如果您现在就 开始执行并发操作,则不会遇到这种情况。本文将介绍需要注意的一些较为常见的挑战,并针对您在软件中如何运用它们给出一些建议。 首先我将讨论在并发程序中经常会出错的一类问题。我把它们称为“安全隐患”,因为它们很容易发现并且后果通常比较严重。这些危险会导致您的程序因崩溃或内存问题而中断。当 从多个线程并发访问数据时会发生数据争用(或竞争条件)。特别是,在一个或多个线程写入一段数据的同时,如果有一个或多个线程也在读取这段数据,则会发生 这种情况。之所以会出现这种问题,是因为Windows 程序(如C++ 和Microsoft .NET Framework

多线程高效访问共享资源

多线程高效访问共享资源 -------BY 懒牛 一、多线程访问共享资源需注意的问题: 1、多个线程如果在一个进程内,可共享进程内的资源。 2、多个线程在不同的进程内,不同进程的资源不能直接共享,要用到内存映射文件。 3、访问方式是用户方式还是内核方式,用户方式速度快,内核方式速度慢。 二、用户方式和内核方式的区别: 1、书上说的用户方式有互锁函数,CRITICAL_SECTION关键代码段,内核方式有信标、事件、互斥量。但是关键代码段也不是完全的用户方式,当一个线程进入关键代码段访问资源,另一个线程是进入内核方式等待的。也是很费时间。经过理解,我认为:用户方式是指当一个线程占有资源时,另外的线程是以什么方式在等待。 2、平常让程序等待的方式有三种,一种是让程序不断的条件循环,当条件达到时,退出。这是最标准的用户方式,依靠循环浪费时间来等待,没用到内核。第二种用sleep()函数,这个不太好用条件控制,本质上也是内核方式。第三种就是内核的Waitfor…..之类的等待函数了。 3、从浪费时间的程度上来看,要分CPU是单核还是多核的,如果是单核的,用户方式的条件循环最浪费时间,因为单核时循环要不断的在几个线程上下文切换特浪费时间;内核方式其次,所以在单核情况下,我们多线程访问资源,就直接用内核方式就OK了。在多核方式下情况有变化,一个线程在第一个CPU上访问资源时,另一个线程可以使用第二个CPU来在用户方式下做条件循环来判断是否能够访问资源了。多核方式下是真正的并发访问,二个线程同时运行,不用做上下文切换。如果这种访问资源的时间用时很短,比如说:一个线程只是在资源上做一个简单运算就离开,则另一个线程在几个用户循环的判断时间就能够访问资源了,何苦要进入内核方式呢?所以在对共享资源访问时,我们先在用户方式下做几个循环来判断,如果能访问了,OK进行访问,如果循环到一定时间,还是不能访问资源,说明这种资源的访问很费时间,在用户方式下继续做循环不合算了,我们就换成内核方式,让系统去帮我等待去吧,我们不管了,哈哈! 三、多线程访问共享资源总结如下: 1、单核时直接进入内核方式等待,等待成功则访问资源。 2、多核时先在用户方式下做循环不断的询问是否能访问,到达一定循环次数,如果条件满足则访问,如果到循环最大值仍然不能访问,则我们也不浪费时间,直接转内核方式等待。 WINDOWS核心编程中为高效访问共享资源,编制了COptex类,使用这个类建立的对象就是多个线程要访问的共享资源,下面让我们来详细分析一下: 表1-1 成员变量描述

Linux学习之线程体传递参数

在线学习好工作https://www.360docs.net/doc/7b16833129.html,/ Linux学习之线程体传递参数 传递参数的两种方法 线程函数只有一个参数的情况:直接定义一个变量通过应用传给线程函数。例子 #include #include using namespace std; pthread_t thread; void * fn(void *arg) { int i = *(int *)arg; cout<<"i = "<

操作系统以进程为单位分配资源。 线程是执行单位,线程函数有多个参数的情况:这种情况就必须申明一个结构体来包含所有的参数,然后在传入线程函数。 具体请查看代码: Mularg.c #include #include #include #include typedef struct arg_struct ARG ; struct arg_struct { char name[10] ; int age ; float weight ; } ; void * thfn ( void * arg ) { ARG * p = (ARG *) arg ; printf( " name is : %s , age is : % d , weight is : %f \ n " , p->name , p->age , p->weight ) ; return NULL ; } int main(int argc , char *argv [ ] ) { pthread_t tid ;

C#给线程传递参数有3种方式

C#给线程传递参数有3种方式 从《C#高级编程》了解到给线程传递参数有两种方式,一种方式是使用带ParameterizedThreadStart委托参数的Thread构造函数;另一种方式是创建一个自定义类,把线程的方法定义为实例的方法,这样就可以初始化实例的数据,之后启动线程。 方式一:使用ParameterizedThreadStart委托 如果使用了ParameterizedThreadStart委托,线程的入口必须有一个object类型的参数,且返回类型为void。且看下面的例子: using System;using System.Threading;namespace ThreadWithParameters{ class Program { static void Main(string[] args) { string hello = "hello world"; //这里也可简写成Thread thread = new Thread(ThreadMainWith Parameters); //但是为了让大家知道这里用的是ParameterizedThreadStart委托,就没有简写了 Thread thread = new Thread(new ParameterizedThreadStart(T hreadMainWithParameters)); thread.Start(hello); Console.Read(); } static void ThreadMainWithParameters(object obj) { string str = obj as string; if(!string.IsNullOrEmpty(str)) Console.WriteLine("Running in a thread,received: {0}", str); } } } 这里稍微有点麻烦的就是ThreadMainWithParameters方法里的参数必须是object类型的,我们需要进行类型转换。为什么参数必须是object类型呢,各位看看ParameterizedThreadStart委托的声明就知道了。 public delegate void ParameterizedThreadStart(object obj); //ParameterizedThreadStart委托的声明 方式二:创建自定义类

C#多线程参数传递

C#多线程参数传递 在多线程或单线程任务中,让线程带传入参数一直是个麻烦的问题,通常有种方法就是以类,对像的变量来传参数,这种方法理解上很简单不过在某些场合使用很麻烦,这里就不介绍了,我们主要介绍一种.NET2.0中新增加的带参数运行线程的方法,示例程序如下: ParameterizedThreadStart ParStart = new ParameterizedThreadStart(ThreadMethod); Thread myThread = new Thread(ParStart); object o = “hello”; myThread.Start(o); ThreadMethod如下: public void ThreadMethod(object ParObject) { //程序代码 } 如果是多参数的话可以以数组或动态列表等方式装相入 object,然后使用时拆箱即可 这样是不是简单多了哈,,, ———————————————————————————– [转]个人认为,还是为线程创建一个单独的类,在类的初始化函数里头为类里头的变量赋值,来达到传入参数比较简单。下面有些方法是有问题的,不过我已经达到了目的就懒得去排错了,哪位朋友看出问题了提醒一下啊。呵呵… 方法一: 在VS2003中,也不能直接访问,参看 一般来说,直接在子线程中对窗体上的控件操作是会出现异常,这是由于子线程和运行窗体的线程是不同的空间,因此想要在子线程来操作窗体上的控件,是不可能简单的通过控件对象名来操作,但不是说不能进行操作,微软提供了Invoke的方法,其作用就是让子线程告诉窗体线程来完成相应的控件操作。 现在用一个用线程控制的进程条来说明,大致的步骤如下: 1.创建Invoke函数,大致如下: /// /// Delegate function be invoked by main thread ///

多线程在按键精灵中的应用

个人认为多线程没什么复杂的 重要的在于参数传递 一个线程返回一个线程ID 如果你要想在子程序里面暂停他就得把线程的ID传递进去才能暂停 因为普通变量的参数传递不到线程中所以很多人就觉得在线程中无法暂停线程 比如 1.a=BeginThread(程序1) 2.b=BeginThread(程序2) 3.sub 程序1 4. 5.end sub 6. 7.sub 程序2 8. 9.end sub 复制代码 这是2个线程在线程中我们是无法暂停线程的只能在线程外暂停 因为他的线程ID是无法传递进线程中得所以没法暂停找不到目标这就是很多人不明白为什么线程中无法暂停线程的原因如果还不理解那么大家看看另一个 a=BeginThread(程序1) b=BeginThread(程序2) MessageBox a sub 程序1 MessageBox a end sub sub 程序2

end sub [/code] 这个线程多线程中会弹出2个窗口弹出的是第一个线程返回的值 弹出的2个值我们会发现不一样因为多线程中参数没有传递进去所以弹出的是空白 而另一个在线程外所以就值了 我们就会发现每个线程运行都会返回一个线程ID 因为线程返回的值存入的变量是普通变量无法传递进去所以在线程中我们暂停或者停止都是无效的但是我们把返回值定义成环境变量就能传递进去了 DimEnv a a=BeginThread(程序1) b=BeginThread(程序2) MessageBox a sub 程序1 MessageBox a end sub sub 程序2 //这里是我要运行的代码 end sub [/code] 这样在线程中和线程外弹出的值就是一样的 那么我们就能随意停止线程了 不管你在哪个线程中暂停都会停止线程 这样一来多线程就很容易理解了 我们只需要搞清楚在多线程中运行的多线程主线程停止子线程是不会停止的

Linux中多线程编程并传递多个参数

解析Linux中多线程编程并传递多个参数 Linux中多线程编程并传递多个参数实例是本文讲解的内容,不多说,先来看内容。 Linux下的多线程编程,并将多个参数传递给线程要执行的函数。 以下是实验程序的源代码: pthread.c #include #include #include #include #include struct argument { int num; char string[30]; }; int main() { int i,ret; void *thread1_func(void *); void *thread2_func(void *); void *thread_return1,*thread_return2;/*用来接收两个线程退出后的返回值*/ pthread_t thread1,thread2; struct argument arg1,arg2; arg1.num=1949; strcpy(arg1.string,"中华人民共和国成立"); arg2.num=2009; strcpy(arg2.string,"建国六十周年"); pthread_create(&thread1,NULL,thread1_func,(void *)&arg1); pthread_create(&thread2,NULL,thread2_func,(void *)&arg2); for(i=0;i<=2;i++) { printf("我是最初的进程!\n"); sleep(2); } ret=pthread_join(thread1,&thread_return1);/*等待第一个线程退出,并接收它的返回值*/ if(ret!=0) printf("调用pthread_join获取线程1返回值出现错误!\n"); else printf("pthread_join调用成功!线程1退出后带回的值是%d\n",(int)thread_return1);

CreateThread使用(六个参数介绍)

CreateThread使用(六个参数介绍) function CreateThread( lpThreadAttributes: Pointer; {安全设置} dwStackSize: DWORD; {堆栈大小} lpStartAddress: TFNThreadStartRoutine; {入口函数} lpParameter: Pointer; {函数参数} dwCreationFlags: DWORD; {启动选项} var lpThreadId: DWORD {输出线程ID } ): THandle; stdcall; {返回线程句柄} 1、返回值:返回线程句柄 "句柄" 类似指针, 但通过指针可读写对象, 通过句柄只是使用对象; 有句柄的对象一般都是系统级别的对象(或叫内核对象); 之所以给我们的是句柄而不是指针, 目的只有一个: "安全"; 貌似通过句柄能做很多事情, 但一般把句柄提交到某个函数(一般是系统函数)后, 我们也就到此为止很难了解更多了; 事实上是系统并不相信我们. 不管是指针还是句柄, 都不过是内存中的一小块数据(一般用结构描述), 微软并没有公开句柄的结构细节, 猜一下它应该包括: 真实的指针地址、访问权限设置、引用计数等等. 既然CreateThread 可以返回一个句柄, 说明线程属于"内核对象". 实际上不管线程属于哪个进程, 它们在系统的怀抱中是平等的; 在优先级(后面详谈)相同的情况下, 系统会在相同的时间间隔内来运行一下每个线程, 不

过这个间隔很小很小, 以至于让我们误以为程序是在不间断地运行. 这时你应该有一个疑问: 系统在去执行其他线程的时候, 是怎么记住前一个线程的数据状态的? 有这样一个结构TContext, 它基本上是一个CPU 寄存器的集合, 线程是数据就是通过这个结构切换的, 我们也可以通过GetThreadContext 函数读取寄存器看看. 附上这个结构TContext(或叫: CONTEXT、_CONTEXT) 的定义: PContext = ^TContext; _CONTEXT = record ContextFlags: DWORD; Dr0: DWORD; Dr1: DWORD; Dr2: DWORD; Dr3: DWORD; Dr6: DWORD; Dr7: DWORD; FloatSave: TFloatingSaveArea; SegGs: DWORD; SegFs: DWORD; SegEs: DWORD; SegDs: DWORD; Edi: DWORD; Esi: DWORD; Ebx: DWORD; Edx: DWORD; Ecx: DWORD; Eax: DWORD; Ebp: DWORD; Eip: DWORD; SegCs: DWORD; EFlags: DWORD; Esp: DWORD; SegSs: DWORD; end;

Win32多线程编程 — 线程同步与通信

一.线程间数据通信 系统从进程的地址空间中分配内存给线程栈使用。新线程与创建它的线程在相同的进程 上下文中运行。因此,新线程可以访问进程内核对象的所有句柄、进程中的所有内存以及同 一个进程中其他所有线程的栈。这样一来,同一个进程中的多个线程可以很容易的相互通信。 到目前为止,将数据从一个线程传到另一个线程的惟一方法是在创建线程时传递给新线 程一个指针参数(LPVOID lpParam)。参数lpParam为LPVOID指针类型,我们可在其中 存储普通的数值(size为平台地址总线宽度),也可以存放指向某个数据结构(struct 或class)的地址。在新线程函数中,解引用时需要强制类型转换回原类型,以进行正确 的访问。 以下代码段演示了一个典型的多线程场景。 // A typical multithread scene DWORD WINAPI FirstThread(PVOID lpParam) { // Initialize a stack-based variable int x = 0; DWORD dwThreadID; // Create a new thread. HANDLE hThread = CreateThread(NULL, 0, SecondThread, (LPVOID)&x, 0, &dwThreadID); // We don't reference the new thread anymore, // so close our handle to it. CloseHandle(hThread); // Our thread is done. // BUG:our stack will be destroyed, // but SecondThread might try to access it. return 0; } DWORD WINAPI SecondThread(LPVOID lpParam) { // Do some lengthy processing here. // ... // Attempt to access the variable on FirstThread's stack. // NOTE:This may cause an access violation - it depends on timing! *((int*)lpParam) = 5; // ... return 0; } 上述场景中,Windows没有维持线程之间的“父子关系“,即父线程FirstThread 已经终止运行,而子线程SecondThread仍在继续运行。以上父子关系只是为了一种解说 上的方便,实际上FirstThread和SecondThread具有相同的优先级(默认是 normal),

C#线程传递参数

C#线程传递参数实现主要向你介绍了利用MyThread来为C#线程传递参数的具体实现,希望对你了解和学习C#线程传递参数有所帮助。 C#线程传递参数的实现是如何进行的呢?那么这里我们使用MyThread来为线程传递任意复杂的参数,那么下面就向你详细介绍具体的实现过程。 Thread类有一个带参数的委托类型的重载形式。这个委托的定义如下: 1.[ComVisibleAttribute(false)] 2. 3.public delegate void ParameterizedThreadStart(Object obj) C#线程传递参数之Thread类的构造方法的定义如下: 4.public Thread(ParameterizedThreadStart start); 下面的代码使用了这个带参数的委托向线程传递一个字符串参数: 5.public static void myStaticParamThreadMethod(Object obj) 6.{ 7.Console.WriteLine(obj); 8.} 9. 10.static void Main(string[] args) 11.{ 12.Thread thread = new Thread(myStaticParamThreadMethod); 13. thread.Start("通过委托的参数传值"); 14.} 要注意的是,如果使用的是不带参数的委托,不能使用带参数的Start 方法运行线程,否则系统会抛出异常。但使用带参数的委托,可以使用thread.Start()来运行线程,这时所传递的参数值为null。 C#线程传递参数之定义一个类来传递参数值: 实现具体的代码如下: 15.class MyData 16.{ 17.private String d1; 18.private int d2; 19.public MyData(String d1, int d2)

多线程总结

目录 Delphi也提供了一个相同功能的类似函数: (1) Windows API: (2) 参数含义: (2) 强行退出线程 (2) Delphi的TThread类 (3) 派生线程类的方法 (3) 构造函数Create (3) 析构函数 (3) 线程执行Execute (4) OnTerminate事件 (4) 提示:OnTerminate事件是在主线程的环境中发生的。这意味着,在处理这个事件的处理过程中,你可以不需要借助于Synchronize()而自由地访问VCL。 (4) 等待线程结束的WaitFor (4) 注意:在主线程中要慎用waitfor,否则可能导致主线程死锁。 (5) 设置线程的优先级 (5) 临界区(CriticalSection) (5) 多线程同时访问可视对象库VCL (6) 线程的Synchronize函数 (6) 总结 (7) Delphi也提供了一个相同功能的类似函数: function BeginThread(SecurityAttributes: Pointer; StackSize: LongWord; ThreadFunc: TThreadFunc; Parameter: Pointer; CreationFlags: LongWord; var ThreadId: LongWord): Integer;

? Windows API: HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId ); 参数含义: 线程属性(用于在NT下进行线程的安全属性设置,在9X下无效),堆栈大小,起始地址,参数,创建标志(用于设置线程创建时的状态),线程ID,最后返回线程Handle。其中的起始地址就是线程函数的入口,直至线程函数结束,线程也就结束了。 强行退出线程 ?Windows API: ?VOID ExitThread( DWORD dwExitCode ); ? C Runtime Library: ?void _endthread(void); ?Delphi Runtime Library: ?procedure EndThread(ExitCode: Integer);

相关主题
相关文档
最新文档