-
java多线程编程_java多线程编程
2021-02-12 08:52:18所谓的多线程编程本质上是并发编程,并发编程的本质是指发挥出所有硬件的最大性能。 Java 是为数不多的真正支持有多线程并发编程的开发语言。所以Java 在整体的处理性能上是最高的。如果要了解线程的性能问题,那么...所谓的多线程编程本质上是并发编程,并发编程的本质是指发挥出所有硬件的最大性能。
Java 是为数不多的真正支持有多线程并发编程的开发语言。所以Java 在整体的处理性能上是最高的。
如果要了解线程的性能问题,那么首先要先解决的就是清楚什么叫做进程?
从计算机发展的历史来讲,传统的硬件只有一个 CPU(单核心的CPU),于是为了发挥出硬件的全部性能,引入了多进程的编程模式。
多进程是指在没有扩展原始系统硬件资源的情况下,利用一些算法,可以实现多个进程的并行执行。在同一个时间段上,会有多个进程并发执行,但是在同一个时间点上只会有一个进程执行。
线程实在进程基础上的进一步划分,可以达到更快的处理性能,任何一个进程的启动速度实际上都是非常缓慢的,所以线程本质上的设计性能上要远远高于进程,但是线程不可能离开进程存活。
每一个进程的执行都必须有一个独立执行它的 CPU,所以所有的资源共享里只有 CPU是无法进行共享的,每个进程都有一个自己的中央处理单元。如果要想实现CPU的共享,那么就必须利用线程来描述。
随着硬件和软件的发展,硬件中的CPU出现了多核的状态,理论上多核CPU的多进程执行称为并行编程,并非所有的CPU都可以超出若干个线程出来,一般来讲,每一块CPU 只会有一个线程执行,但是有些CPU 可以使用超线程技术,设计出若干个多线程的执行状态。
在进程和线程的概念之上实际上还有一个所谓的”纤程“,在线程基础上的进一步划分,但有些地方称之为”协程“。Java并没有支持多协程编程(以后可能有)。现在比较常见的编程语言里:Kotlin(Android 第二代产品)和Python都是支持多协程编程的。
所有的Java 程序执行需要通过一个主方法完成,主方法会作为程序的起点。
若要进行多线程编程,也要有一个线程的起点结构。这个结构就称为线程类,所有的线程类都是有继承要求的,可以有三种实现方式:
继承Thread类;
实现Runnable接口;
实现Callable接口;
1)继承Thread实现多线程
java.lang.Thread 是由系统定义的一个线程处理类,任何的子类只需要继承此类,就可以得到一个线程处理的子类,在继承时一定要覆写Thread 类中的 run() 方法,那么这个方法成为线程启动的主方法存在。
范例:定义一个线程的主体类:
如果要想正常的进行多线程的并发执行,那么就要调用本机操作系统提供的底层的函数支持,所以多线程的启动并不是依靠 run()完成的,他需要通过 Start()方法进行启动。而所有的Start() 启动后将调用 run()方法中定义的方法体。
public void start()
范例:启动多线程
class MyThread extendsThread{privateString name;publicMyThread(String name){this.name =name;
}
@Overridepublic voidrun() {//覆写run()方法
for (int i =0; i<50;i++){
System.out.println("【"+this.name+"- 线程】运行,i="+i);
}
}
}public classMyBlog2 {public static voidmain(String[] args) {
MyThread threadA= new MyThread("线程A");
MyThread threadB= new MyThread("线程B");
MyThread threadC= new MyThread("线程C");
threadA.start();//通过Thread 类继承而来
threadB.start();
threadC.start();
}
}
运行结果(随机抽取):
...................
【线程A- 线程】运行,i=49【线程C- 线程】运行,i=0【线程B- 线程】运行,i=0【线程C- 线程】运行,i=1【线程B- 线程】运行,i=1
..................
通过执行的结果,所有的线程对象属于交替的执行过程,并且都在交替执行run() 方法定义的方法体。进一步的解释:关于start() 方法?
首先观察start() 的实现源代码:
public synchronized voidstart() {if (threadStatus != 0)throw newIllegalThreadStateException();
group.add(this);boolean started = false;try{
start0();
started= true;
}finally{try{if (!started) {
group.threadStartFailed(this);
}
}catch(Throwable ignore) {
}
}
}privatenative voidstart0();
@Overridepublic voidrun() {if (target != null) {
target.run();
}
}
在每一个start()方法里都会抛出 “IllegalThreadStateException” 异常,而此异常是 RuntimeException 的一个子类,用户可以根据自己的需要选择性处理,此异常在重复启动多线程的时候才会抛出。
此时会发现 start()方法里定义了一个 start0()方法,而start0()方法没有方法体,但是使用了一个native的关键字定义,此关键字的作用在于此操作将交由底层实现。
在Java开发领域存在一个称为 JNI(Java Native Iterface)的技术,利用Java 技术调用底层操作系统函数,但是一般JavaEE 中这个开发较少见,因为这样写,Java的可移植性就会丧失,在之前的Android 开发里,JNI技术比较常见。
public classMyBlog2 {public static voidmain(String[] args) {
MyThread threadA= new MyThread("线程A");
MyThread threadB= new MyThread("线程B");
MyThread threadC= new MyThread("线程C");
threadA.start();//通过Thread 类继承而来
threadB.start();
threadC.start();
threadC.start(); //让他重复启动
}
}
Exception in thread "main" java.lang.IllegalThreadStateException
at java.base/java.lang.Thread.start(Thread.java:794)
at ThreadTest.MyBlog2.main(MyBlog2.java:24)
【线程A- 线程】运行,i=0【线程C- 线程】运行,i=0....................................
//省略下面。。
一个线程只允许启动一次。
2)实现 Runnable 接口
除了使用 Thread 类实现多线程之外,也可以使用java.lang .Runnable 接口来完成,首先观察一下Runnable 接口。
@FunctionalInterfacepublic interfaceRunnable{public voidrun();
}
在Runnable 接口中同样存在有一个 run() 方法,此方法作为线程主方法存在。
使用Runnable实现多线程:
class MyThread implementsRunnable{privateString name;publicMyThread(String name){this.name =name;
}
@Overridepublic voidrun() {//覆写run()方法
for (int i =0; i<50;i++){
System.out.println("【"+this.name+"- 线程】运行,i="+i);
}
}
}
在之前继承了 Thread类实现的多线程,会自动将父类的 start方法继承而来,但若使用Runnable来实现,该接口并没有提供 start() 方法,同时关键型的问题是:多线程的启动只能够依靠Thread 类的 start() 方法。所以此时关注一下Thread类里提供的构造方法:
public Thread(Runnable target)
这个构造方法里面需要接受 Runnable 接口对象的实例。那么此时只需要按照标准调用即可。
范例:启动多线程:
public classMyBlog2 {public static voidmain(String[] args) {
MyThread threadA= new MyThread("线程A");
MyThread threadB= new MyThread("线程B");
MyThread threadC= new MyThread("线程C");newThread(threadA).start();newThread(threadB).start();newThread(threadC).start();
}
}
//程序执行结果(随机抽取):
【线程B- 线程】运行,i=0【线程C- 线程】运行,i=0【线程C- 线程】运行,i=1【线程C- 线程】运行,i=2【线程C- 线程】运行,i=3
//..........省略后面的结果了。。。。。。
那么此时就实现了与之前完全相同的操作功能,,但是很明显这样的实现避免了继承带来的单继承的局限,所以更适合项目的编写,同时在JDK1.8之后,Runnable成为了一个函数时接口,所以此时代码也可以使用 Lambda表达式进行定义。
范例:使用Lambda 实现多线程:
public classMyBlog2 {public static voidmain(String[] args) {
String names[]= new String[]{"线程A","线程B","线程C"};for(String name :names) {new Thread(()->{for (int i =0; i<50;i++){
System.out.println("【"+name+"- 线程】运行,i="+i);
}
}).start();
}
}
}
运行结果(部分抽取):
【线程A- 线程】运行,i=3【线程B- 线程】运行,i=26【线程C- 线程】运行,i=30【线程B- 线程】运行,i=27【线程B- 线程】运行,i=28
从JDK1.8 之后 Lambda表达式的出现实际上可以达到简化线程类定义的功能。
Thread 类与Runnable 接口的关系
在JDK 1.0 的时代就提供了 Thread类和 Runnable 接口,所以这两个实现方案就经常被人拿来比较,我将从两者实现的关联及区别进行说明,首先观察一下 Thread 类的定义结构:
public class Thread extends Object implements Runnable
可以发现此时的 Thread 类也是 Runnable 接口的子类,所以可以得到如下结构图:
解释问题:为什么Thread 接受了 Runnable 接口对象之后会去调用真实线程中的 run() 方法?
1、关注 Thread类中接受 Runnable 接口对象的构造方法:
publicThread(Runnable target) {this(null, target, "Thread-" + nextThreadNum(), 0);
}
this.target = target;
private Runnable target;
当Runnable 接口传到 Thread 类中之后,会自动利用Thread类中的target 属性保存 Runnable 接口实例。
2、观察 Thread类中的 run() 方法(调用start()就调用Thread 类中的run()方法)
@Overridepublic voidrun(){if (target != null){
target.run();
}
}
可以发现在 Thread.run()方法定义的时候会判断是否有 target 实例,如果有实例,则会调用相应的run()方法;
在两种多线程实现方法下,实际上Runnable 接口相比较 Thread 而言,可以更加方便的描述数据共享的概念,即多个线程并行操作同一个资源(方法体)。
范例:观察资源共享:
class Mythread implementsRunnable{privateString name;private int ticket = 20; //共买20张票
@Overridepublic voidrun() {for (int x = 0; x < 50; x++) {if (this.ticket >0){
System.out.println("- 卖票:"+ticket--);
}
}
}
}public classMyBlog1 {public static voidmain(String[] args) {
Mythread threadBody=new Mythread();//定义多线程的公共处理
newThread(threadBody).start();newThread(threadBody).start();newThread(threadBody).start();
}
}
运行结果(部分抽取):- 卖票:20
- 卖票:19
- 卖票:18
- 卖票:16
- 卖票:17
- 卖票:14
classMyThread extendsThread{
privateString name;
publicMyThread(String name){
this.name=name;
}
@Overridepublic voidrun() {
//覆写run()方法for(inti =0; i<50;i++){
System.out.println("【"+this.name+"- 线程】运行,i="+i);
}
}
}
public classMyBlog2 {
public static voidmain(String[] args) {
MyThread threadA = newMyThread("线程A");
MyThread threadB = newMyThread("线程B");
MyThread threadC = newMyThread("线程C");
threadA.start(); //通过Thread 类继承而来threadB.start();
threadC.start();
}
}
-
多线程编程(python语言)
2018-08-10 16:47:56众所周知,多线程编程是一种可以提高整个任务性能的并行处理方式。多线程编程的主要特点有以下几个方面,本质上是异步的;需要多个并发活动;每个活动的处理顺序可能是不确定的,或者说是随机的、不可预测的。这种...众所周知,多线程编程是一种可以提高整个任务性能的并行处理方式。多线程编程的主要特点有以下几个方面,本质上是异步的;需要多个并发活动;每个活动的处理顺序可能是不确定的,或者说是随机的、不可预测的。这种编程任务可以被组织或划分成多个执行流,其中每个执行流都有一个指定要完成的任务。根据应用的不同,这些子任务可能需要计算出中间结果,然后合并为最终的输出结果。在学习多线程的一个主要的误区就是,不要认为多线程就是计算机同时运行多个线程,实际上在程序运行的任意时间,只有一个线程会被解释器运行。
Python 提供了多个模块来支持多线程编程,包括 thread、threading 和 Queue 模块等。程序是可以使用 thread 和 threading 模块来创建与管理线程。thread模块提供了基本的线程和锁定支持;而threading模块提供了更高级别、功能更全面的线程管理。使用 Queue 模块,用户可以创建一个队列数据结构,用于在多线程之间进行共享。(PS:避免使用thread模块,应尽量使用更高级别的线程管理模块,如threading模块。不使用thread模块的一个主要原因是它对于子进程何时退出没有控制,一旦主进程结束,其它进程均强制退出。)在这里要引入一个新的概念,守护进程,如果一个进程被设置为守护进程,就表示这个进程不太重要,当主进程退出时不需要等待该进程执行完成。下面来举几个多线程的例子。
import threading from time import ctime,sleep class MyThread(threading.Thread): def __init__(self,func,args,name=''): threading.Thread.__init__(self) self.name=name self.func=func self.args=args def getResult(self): return self.res def run(self): print 'starting',self.name,'at:',ctime() self.res=self.func(*self.args) print self.name,'finished at:',ctime()
该程序将多线程封装成MyThread类,以后使用时可直接调用。
from random import randint from time import sleep from Queue import Queue from myThread import MyThread def writeQ(queue): print 'producing object for Q...',queue.put('xxx',1) print "size now",queue.qsize() def readQ(queue): val=queue.get(1) print 'CONSUMED object from Q... size now',queue.qsize() def writer(queue,loops): for i in range(loops): writeQ(queue) sleep(randint(1,3)) def reader(queue,loops): for i in range(loops): readQ(queue) sleep(randint(2,5)) funcs=[writer,reader] nfuncs=range(len(funcs)) def main(): nloops=randint(2,5) q=Queue(32) threads=[] for i in nfuncs: t=MyThread(funcs[i],(q,nloops),funcs[i].__name__) threads.append(t) for i in nfuncs: threads[i].start() for i in nfuncs: threads[i].join() print 'all done' if __name__=='__main__': main()
该例子调用MyThread实例,完成简单的函数调用。
我觉得里边的函数什么都不用记,如果以后要用到多线程的话,将这个框架做相应的修改就行了。
本人对计算机视觉比较感兴趣,有兴趣的大神可以多多交流。
-
Java学习路线-14:多线程编程
2019-11-13 23:48:58第1 章 : Java多线程编程 ...Java多线程编程语言 3 Thread类实现多线程 1、继承Java.lang.Thread实现多线程 覆写run方法 start启动线程 每一个线程对象只能启动一次,多次启动就会抛出异常 native JNI Java Nat...第1 章 : Java多线程编程
2 进程与线程
进程 系统进行资源分配和调度的基本单位
线程 在进程基础上划分的更小的程序单元,操作系统能够进行运算调度的最小单位Java多线程编程语言
3 Thread类实现多线程
1、继承Java.lang.Thread实现多线程
覆写run方法
start启动线程每一个线程对象只能启动一次,多次启动就会抛出异常
native
JNI Java Nativa Interface 本地接口,针对不同操作系统有不同的实现
class MyThread extends Thread{ private String name; public MyThread(String name){ this.name = name; } @Override public void run(){ for (int i =0 ; i< 3; i++) { System.out.println(this.name + " -> " + i); } } } class Demo{ public static void main(String[] args) { new MyThread("A").start(); new MyThread("B").start(); new MyThread("C").start(); /** A -> 0 A -> 1 A -> 2 C -> 0 B -> 0 B -> 1 B -> 2 C -> 1 C -> 2 */ } }
4 Runnable接口实现多线程
JDK >= 1.8 变为函数式接口
Thread类有单继承局限class MyThread implements Runnable{ private String name; public MyThread(String name){ this.name = name; } @Override public void run(){ for (int i =0 ; i< 3; i++) { System.out.println(this.name + " -> " + i); } } } class Demo{ public static void main(String[] args) { Thread t1 = new Thread(new MyThread("A")); Thread t2 = new Thread(new MyThread("B")); Thread t3 = new Thread(new MyThread("C")); t1.start(); t2.start(); t3.start(); /** A -> 0 A -> 1 A -> 2 C -> 0 B -> 0 B -> 1 C -> 1 C -> 2 B -> 2 */ } }
利用Runnable + Lambda实现
class Demo{ public static void main(String[] args) { for(int i=0; i< 3; i++) { String name = "对象-" + i ; Runnable run = ()->{ for(int j=0; j< 3; j++) { System.out.println(name + "-> " + j); } }; new Thread(run).start(); } /** 对象-0-> 0 对象-0-> 1 对象-0-> 2 对象-1-> 0 对象-2-> 0 对象-1-> 1 对象-1-> 2 对象-2-> 1 对象-2-> 2 */ } }
利用Thread + Lambda实现
class Demo{ public static void main(String[] args) { for(int i=0; i< 3; i++) { String name = "对象-" + i ; new Thread(()->{ for(int j=0; j< 3; j++) { System.out.println(name + "-> " + j); } }).start(); } /** 对象-0-> 0 对象-0-> 1 对象-0-> 2 对象-1-> 0 对象-2-> 0 对象-1-> 1 对象-1-> 2 对象-2-> 1 对象-2-> 2 */ } }
多线程优先考虑Runnable 实现,永远都是Thread.start() 启动
5 Thread与Runnable关系
class Thread implements Runnable
Thread 代理类
MyThread implements Runnable 实际业务使用了代理设计模式
Thread t = new Thread(new MyThread());
Thread类启动多线程调用的是start()方法,而后启动run()方法
Thread类接收Runnable 接口对象,调用start()方法后,会启动Runnable 接口对象的run()方法多线程实质上在于多个线程可以进行同一资源的抢占
Thread 描述的是线程
Runnable 描述资源class MyThread implements Runnable{ private int ticket = 5; public void run() { while (true){ if(ticket > 0){ System.out.println(ticket-- ); }else{ break; } } } } public class Demo { public static void main(String[] args) { MyThread t = new MyThread(); Thread t1 = new Thread(t); Thread t2 = new Thread(t); Thread t3 = new Thread(t); t1.start(); t2.start(); t3.start(); /** * 5 * 3 * 2 * 1 * 4 */ } }
6 Callable接口实现多线程
JDK >= 1.5
java.util.concurrent.Callable@FunctionalInterface public interface Callable<V> { V call() throws Exception; }
继承关系
class Thread implements Runnable public interface RunnableFuture<V> extends Runnable, Future<V> public class FutureTask<V> implements RunnableFuture<V> {
import java.util.concurrent.Callable; import java.util.concurrent.FutureTask; import java.util.concurrent.ExecutionException; class MyThread implements Callable<String>{ public String call() { return "线程执行完毕"; } } public class Demo { public static void main(String[] args) throws ExecutionException, InterruptedException { FutureTask<String> task = new FutureTask<String>(new MyThread()); new Thread(task).start(); System.out.println(task.get()); // 线程执行完毕 } }
区别 Callable Runnable
Runnable JDK1.0 只有run方法,没有返回值
Callable JDK1.5 提供call方法,有返回值7 多线程运行状态
线程生命周期
创建 start() 就绪 运行 run() 阻塞 终止
第2 章 : 线程常用操作方法
8 线程的命名和取得
获取当前线程对象
public static native Thread currentThread();
线程自动命名,使用 static
import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; class MyThread implements Runnable { public void run() { System.out.println(Thread.currentThread().getName()); } } public class Demo { public static void main(String[] args) throws ExecutionException, InterruptedException { MyThread t = new MyThread(); new Thread(t, "线程A").start(); new Thread(t).start(); new Thread(t, "线程B").start(); /** * 线程A * 线程B * Thread-0 */ } }
主线程
public static void main(String[] args) throws ExecutionException, InterruptedException { System.out.println(Thread.currentThread().getName()); // main }
主线程可以创建若干子线程
主线程控制主体流程
子线程执行耗时操作9 线程休眠
线程暂缓执行
Exception 必须处理
class InterruptedException extends Exception public static native void sleep(long millis) throws InterruptedException; public static void sleep(long millis, int nanos) throws InterruptedException;
休眠线程
public class Demo { public static void main(String[] args) { new Thread(()->{ for (int i= 0; i< 3; i++){ System.out.println(i); // 暂停一秒 try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); } }
10 线程中断
中断线程执行
public void interrupt()
判断线程是否被中断
public boolean isInterrupted()
所有线程都可以被中断,中断异常必须处理
public class Demo { public static void main(String[] args) { Thread t = new Thread(() -> { // 暂停10秒 try { Thread.sleep(10 * 1000); } catch (InterruptedException e) { e.printStackTrace(); } }); t.start(); if (!t.isInterrupted()) { t.interrupt(); } // 抛出异常 sleep interrupted } }
11 线程强制运行
线程独占资源,一直到线程执行结束
public final void join() throws InterruptedException
public class Demo { public static void main(String[] args) { Thread mainThread = Thread.currentThread(); Thread t = new Thread(() -> { // 强制执行主线程 try { mainThread.join(); } catch (InterruptedException e) { e.printStackTrace(); } for (int i = 0; i < 3; i++) { System.out.println(Thread.currentThread().getName() + " " + i); } }); t.start(); for (int i = 0; i < 3; i++) { System.out.println(Thread.currentThread().getName() + " " + i); } // 抛出异常 sleep interrupted } }
12 线程礼让
yield 产生;让步
每一次调用yield()方法只会礼让一次当前的资源
public static native void yield();
public class Demo { public static void main(String[] args) { Thread t = new Thread(() -> { for (int i = 0; i < 30; i++) { System.out.println("礼让资源"); Thread.yield(); System.out.println(Thread.currentThread().getName() + " " + i); } }); t.start(); for (int i = 0; i < 30; i++) { System.out.println(Thread.currentThread().getName() + " " + i); } } }
13 线程优先级
线程优先级越高,越可能先执行,可能优先抢占到资源
public final int getPriority() public final void setPriority(int newPriority)
优先级常量
MIN_PRIORITY = 1; NORM_PRIORITY = 5; MAX_PRIORITY = 10;
主线程优先级,和默认优先级都是中等优先级 5
public class Demo { public static void main(String[] args) { System.out.println(Thread.currentThread().getPriority()); // 5 } }
-
Java语言多线程编程精要之实现线程
2020-03-04 12:36:46Thread类是一个具体的类,即不是抽象类,该类封装了线程的行为。要创建一个线程,程序员必须创建一个从Thread类导出的新类。程序员必须覆盖Thread的run()函数来完成有用的工作。用户并不直接调用此函数;而是必须... -
C 语言多线程编程
2019-09-03 10:12:50一、Linux 下相关函数 函数 描述 ...int pthread_create(pthread_t thread, pthread_attr_t * attr, void (*start_routine...参数说明:thread: 是一个指针,线程创建成功时,用以返回创建的线程IDattr:指定线...一、Linux 下相关函数
函数 描述 int pthread_create
(pthread_t *thread, pthread_attr_t * attr, void* (*start_routine)(void *),void *arg);创建一个新的线程。 编译时带上-lpthread
.参数说明:
thread: 是一个指针,线程创建成功时,用以返回创建的线程ID
attr:指定线程属性,NULL表示使用默认属性
start_routine:函数指针,指向线程创建后要调用的函数。这个被线程调用的函数也称为线程函数
arg:该参数指向传递给线程函数的参数extern int pthread_join
__P (pthread_t __th, void **__thread_return);用来等待一个线程的结束。 参数说明:
__th:被等待的线程标识符
__thread_return:一个用户定义的指针,它可以用来存储被等待线程的返回值。extern void pthread_exit
__P ((void *__retval)) attribute ((noreturn));终止指定线程。 参数说明:
__retval:函数的返回代码,只要pthread_join中的第二个参数
thread_return不是NULL,这个值将被传递给 thread_returnint pthread_create(pthread_t thread, pthread_attr_t * attr, void (*start_routine)(void *),void *arg); extern int pthread_join __P (pthread_t __th, void **__thread_return); extern void pthread_exit __P ((void *__retval)) attribute ((noreturn));
二、锁
2.1 互斥锁
extern int pthread_mutex_init (pthread_mutex_t *__mutex, const pthread_mutexattr_t *__mutexattr) __THROW __nonnull ((1));
函数
pthread_mutex_init
用来生成一个互斥锁。
NULL参数表明使用默认属性。如果需要声明特定属性的互斥锁,须调用函数 pthread_mutexattr_init.
函数pthread_mutexattr_setpshared
和函数pthread_mutexattr_settype
用来设置互斥锁属性。
前一个函数设置属性pshared
,它有两个取值,PTHREAD_PROCESS_PRIVATE
和PTHREAD_PROCESS_SHARED
.前者用来对不同进程中的线程同步,后者用于同步本进程的不同线程。
后者用来设置互斥锁类型,可选的类型有PTHREAD_MUTEX_NORMAL
、PTHREAD_MUTEX_ERRORCHECK
、PTHREAD_MUTEX_RECURSIVE
和PTHREAD _MUTEX_DEFAULT
.它们分别定义了不同的上所、解锁机制,一般情况下,选用最后一个默认属性。2.1 pthread_mutex_lock 与 pthread_mutex_unlock
extern int pthread_mutex_lock (pthread_mutex_t *__mutex) __THROWNL __nonnull ((1));
extern int pthread_mutex_unlock (pthread_mutex_t *__mutex) __THROWNL __nonnull ((1));
pthread_mutex_lock
声明开始用互斥锁上锁,此后的代码直至调用pthread_mutex_unlock
为止,均被上锁,即同一时间只能被一个线程调用执行。当一个线程执行到pthread_mutex_lock
处时,如果该锁此时被另一个线程使用,那此线程被阻塞,即程序将等待到另一个线程释放此互斥锁。三、线程休眠
3.1 sleep 与 usleep
extern unsigned int sleep (unsigned int __seconds);
extern int usleep (__useconds_t __useconds);
sleep()
函数的功能是把调用该函数的线程挂起一段时间,单位是秒(s);
usleep()
函数的功能是把调用该函数的线程挂起一段时间 ,单位是毫秒(ms)。四、Windows相关函数
4.1 _beginthreadex 与 _endthreadex
_CRTIMP __cdecl __MINGW_NOTHROW unsigned long _beginthreadex (void *, unsigned, unsigned (__stdcall *) (void *), void *, unsigned, unsigned *);
_beginthreadex
用于创建一个后台线程并即刻执行,直到运行结束或者调用_endthreadex
函数终止线程。
_beginthreadex参数说明 :
- 第一个参数:安全属性,NULL为默认安全属性。
- 第二个参数:指定线程堆栈的大小。如果为0,则线程堆栈大小和创建它的线程相同。
- 第三个参数:指定线程函数的地址,也就是线程调用执行函数地址。
- 第四个参数:传递给线程的参数的指针,可以通过传入对象的指针,在线程函数中再转化为对应类型的指针
- 第五个参数:线程初始状态,0:立即运行;CREATE_SUSPEND:suspended(悬挂)。
- 第六个参数:用于记录线程ID的地址。
4.2 WaitForSingleObject
-
Rust语言的多线程编程
2016-09-09 01:06:00我写这篇短文的时候,正值Rust1.0发布不久,严格来说这是一门兼具C语言的执行...下面我注重介绍Rust的多线程编程是怎样,其中大部分内容参考翻译自Rust的官方文档,请看: Concurrency并发 在计算机科学上,并发C... -
多线程编程有什么用途_C++11多线程编程(一)——初始多线程
2020-12-10 07:40:04单线程编程做的好好的,又简单又好用,为什么要弄出一个多线程编程呢?难道前人是为了设计而设计了个多线程的?显然这是不可能,那么是什么原因呢?用最精炼的语言概括无非就是以下两个原因。效率和用户体验效率主要... -
go语言多线程入门笔记-多线程编程
2018-09-17 21:37:11创建线程(pthread)比创建进程(thread)要简单多了,你知道为什么吗?因为一个进程里的多个线程一定运行的是一个程序,所以共享资源变的简单。 同时每个线程都有唯一的ID,而且是系统分配的,这个ID可以复用,你的... -
多线程编程基础
2021-01-31 18:53:51多线程编程基础 多线程编程基础基础概念进程启动进程的方法启动进程方法1启动进程方法2练习:动态生成代码并编译执行进程的三大特征僵尸进程和孤儿进程并行与并发主线程进程中线程之间的关系进程和线程的关系线程和... -
Python多线程编程之多线程加锁操作示例
2020-12-24 20:45:24本文实例讲述了Python多线程编程之多线程加锁操作。分享给大家供大家参考,具体如下: Python语言本身是支持多线程的,不像PHP语言。 下面的例子是多个线程做同一批任务,任务总是有task_num个,每次线程做一个任务... -
Java多线程编程
2021-01-28 10:27:27Java多线程编程 与其他编程语言相比,Java 给多线程(multithreaded)编程提供了内置的支持。 一条线程(thread)指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。 ... -
c 多线程编程01
2018-10-21 00:53:57用以体会不同编程语言间的多线程编程。借此机会,初步学习一下 C 语言的多线程编程。 第一部分主要内容如下: 线程的基础概念 何时使用线程 使用线程的好处? 线程数量的限制? 线程与进程的关系? 线程的... -
多线程编程
2013-03-31 11:38:05其实C++语言本身并没有提供多线程机制,但Windows系统为我们提供了相关API,我们可以使用它们来进行多线程编程。本文就以实例的形式讲解多线程编程的知识。 创建线程的API函数 C++代码 HAN -
第13章-总结多线程编程的模式语言
2019-03-26 09:48:30文章目录13.1 多线程编程的模式语言13.1.1 模式与模式语言13.2 Single Threaded Execution 模式——能通过这座桥的只有一个人13.3 Immutable 模式——想破坏也破坏不了13.4 Guarded Suspension 模式——等我准备好哦... -
多线程编程有什么用途_为什么要学Python编程语言?入门学Python编程语言主要用途有哪些...
2020-12-12 00:55:33为什么要学Python编程语言?入门学Python编程语言主要用途有哪些?小朋友,你是否有很多问号?没关系,问号再多在小编这都不是事!不过,既然想要学习Python技术,首先你要了解Python,清楚到底学完Python能做哪些,... -
JAVA多线程编程
2018-01-15 12:31:17和其他多数计算机语言不同,Java内置支持多线程编程(multithreaded programming)。 多线程程序包含两条或两条以上并发运行的部分。程序中每个这样的部分都叫一个线程(thread),每个线程都有独立的执行路径。... -
多线程_C++11多线程编程(一)——初始多线程
2020-12-29 05:42:44单线程编程做的好好的,又简单又好用,为什么要弄出一个多线程编程呢?难道前人是为了设计而设计了个多线程的?显然这是不可能,那么是什么原因呢?用最精炼的语言概括无非就是以下两个原因。效率和用户体验效率主要... -
Java 多线程编程
2017-12-13 15:07:05多线程是提高程序运行效率的一种方式,就是让多个互相独立的任务同时运行,他们之间没有相互的依赖(相对的),各线程是并行...多线程的问题与编程语言无关,不管是什么语言,只要是支持多线程(基本所有的编程语言都支 -
C++:多线程编程
2019-06-13 11:41:24在C++11被提出来之前,pthread 线程函数并未在c++提供,并且C++语言本身并没有提供太多的关于多线程编程的 机制,但是在未使用pthread 之前的一段时间中,Windows 为我们提供了相关的API 函数,来创建线程。 1.... -
python多线程编程技术主要应用_Python多线程实际编程方式浅析
2021-01-11 22:46:21在编程语言中,多线程的应用是一个比较重要的应用技术。那么,Python编程语中的多线程应用同样也是非常重要的。我们今天就会为大家详细介绍一下有关Python多线程的相关应用技巧。线程相对进程来说是“轻量级”的,... -
Java深入核心-多线程编程实战
2020-03-06 19:02:12对于一个 Java 程序员而言,能否熟练掌握多线程编程是判断他优秀与否的重要标准之一。因为并发编程是 Java 语言中最为晦涩的知识点,它涉及操作系统、内存、CPU、编程语言等多方面的基础能力,更为考验一个程序员的...
-
混合动力系列轿车出厂检验规范.docx
-
短距离接入互联网-无钱网桥组网方案
-
投标方法论
-
二进制中1的个数
-
信息安全管理与信息安全体系实践.ppt
-
用Go语言来写区块链(一)
-
基于Qt的LibVLC开发教程
-
PPT大神之路高清教程
-
上海大学-数学分析-2000—2010年历年考研试卷.doc.pdf
-
Windows系统管理
-
数据库面试题【十四、主键使用自增ID还是UUID】
-
一天学完MySQL数据库
-
centos忘记密码怎么办?教你如何巧妙解决~
-
华为机试 合并表记录
-
批量生成条形码和二维码.zip
-
华为机试 质数因子
-
华为1+X——网络系统建设与运维(中级)
-
朱老师鸿蒙系列课程第1期-3.鸿蒙系统Harmonyos源码配置和管理
-
自媒体搞笑音效和段子素材
-
工程大面向对象课程设计作品(完整)(也适用于软件工程大实验).7z