linux多线程的总结(pthread用法)

时间:2024.4.27

原创:lobbve223

#include

int pthread_create(pthread_t *restrict tidp,const pthread_attr_t *restrict attr,

void *(*start_rtn)(void),void *restrict arg);

Returns: 0 if OK, error number on failure

第一个参数为指向线程标识符的指针。

第二个参数用来设置线程属性。

第三个参数是线程运行函数的起始地址。

第四个参数是运行函数的参数。

当创建线程成功时,函数返回0,若不为0则说明创建线程失败,常见的错误返回代码为EAGAIN和EINVAL。前者表示系统限制创建新的线程,例如线程数目过多了;后者表示第二个参数代表的线程属性值非法.

pthread_create的用法:由于pthread库不是Linux系统默认的库,所以在使用pthread_create创建线程时,需要在编译中请加-lpthread参数,eg:gcc -o test -lpthrea test.c

例1:

#include "pthread.h"

#include "stdio.h"

void* thread_test(void* ptr)

{ while(1)

printf("i am pthread\n");

}

int main()

{

pthread_t pid;

pthread_create(&pid, NULL, test_thread, NULL);

while(1)

printf("i am main pthread\n");

return 0;

}

例2:

#include

#include

pthread_t id;

int ret;

void thread_1()

{

while(1)

{printf(“I am thread\n”);

sleep(1);

}

}

main()

{ret = pthread_create(&id,NULL,(void*)thread_1,NULL);

if(ret != 0)

printf("Create pthread error!\n");

while(1)

{

printf(“I am main thread\n”);

sleep(2);

}

}

例3:

#include

#include

#include

#include

void *thread_function(void *arg);

char message[] = "Hello World";

int main()

{

int res;

pthread_t a_thread;

void *thread_result;

res = pthread_create(&a_thread, NULL, thread_function, (void *)message);

if (res != 0)

{

perror("Thread creation failed");

exit(EXIT_FAILURE);

}

printf("Waiting for thread to finish...\n");

res = pthread_join(a_thread, &thread_result); //pthread_join 阻塞执行的线程直到某线程结束

if (res != 0)

{

perror("Thread join failed");

exit(EXIT_FAILURE);

}

printf("Thread joined, it returned %s\n", (char *)thread_result);

printf("Message is now %s\n", message);

exit(EXIT_SUCCESS);

}

void *thread_function(void *arg)

{

printf("thread_function is running. Argument was %s\n", (char *)arg);

sleep(3);

strcpy(message, "Bye!");

pthread_exit("Thank you for the CPU time");

}

[root@plinux tmp]# cc -D_REENTRANT -I/usr/include/nptl thread2.c -o thread2 -L/usr/lib/nptl -lpthread

[root@plinux tmp]# ./thread2

thread_function is running. Argument was Hello World

Waiting for thread to finish...

Thread joined, it returned Thank you for the CPU time

Message is now Bye!

pthread_join()

void pthread_exit(void *retval)

int pthread_join(pthread_t pid, void **thread_return)

pthread_join()的调用者将挂起并等待th线程终止,retval是调用pthread_exit()的线程(线程ID为pid)的返回值,如果thread_return不为NULL,则*thread_return=retval。

需要注意的是一个线程仅允许唯一的另一个线程使用 pthread_join()等待本线程的终止,并且被等待的线程应该处于可join状态,即非DETACHED状态。


第二篇:Java线程Thread总结


在Java中创建线程有两种方法:使用Thread类和使用Runnable接口。

要注意的是Thread类也实现了Runnable接口,因此,从Thread类继承的类的实例也可以作为target传入这个构造方法。可通过这种方法实现多个线程的资源共享。 线程的生命周期:

1.新建状态(New):用new语句创建的线程对象处于新建状态,此时它和其它的java对象一样,仅仅在堆中被分配了内存

2.就绪状态(Runnable):当一个线程创建了以后,其他的线程调用了它的start()方法,该线程就进入了就绪状态。处于这个状态的 线程位于可运行池中,等待获得CPU的使用权

3.运行状态(Running): 处于这个状态的线程占用CPU,执行程序的代码

4.阻塞状态(Blocked): 当线程处于阻塞状态时,java虚拟机不会给线程分配CPU,直到线程重新进入就绪状态,它才有机会转到 运行状态。

阻塞状态分为三种情况:

1)、 位于对象等待池中的阻塞状态:当线程运行时,如果执行了某个对象的wait()方法,java虚拟机就回把线程放到这个对象的等待池中

2)、 位于对象锁中的阻塞状态,当线程处于运行状态时,试图获得某个对象的同步锁时,如果该对象的同步锁已经被其他的线程占用,JVM就会把这个线程放到这个对象的琐池中。

3)、 其它的阻塞状态:当前线程执行了sleep()方法,或者调用了其它线程的join()方法,或者发出了I/O请求时,就会进入这个状态中。

一、创建并运行线程

当调用start方法后,线程开始执行run方法中的代码。线程进入运行状态。可以通过Thread类的isAlive方法来判断线程是否处于运行状 态。当线程处于运行状态时,isAlive返回true,当isAlive返回false时,可能线程处于等待状态,也可能处于停止状态。

二、挂起和唤醒线程

一但线程开始执行run方法,就会一直到这个run方法执行完成这个线程才退出。但在线程执行的过程中,可以通过两个方法使线程暂时停止执行。这两个方 法是suspend和sleep。在使用suspend挂起线程后,可以通过resume方法唤醒线程。而使用sleep使线程休眠后,只能在设定的时间 后使线程处于就绪状态(在线程休眠结束后,线程不一定会马上执行,只是进入了就绪状态,等待着系统进行调度)。

虽然 suspend和resume可以很方便地使线程挂起和唤醒,但由于使用这两个方法可能会造成一些不可预料的事情发生,因此,这两个方法被标识为 deprecated(弃用)标记,这表明在以后的jdk版本中这两个方法可能被删除,所以尽量不要使用这两个方法来操作线程。

三、终止线程的三种方法

有三种方法可以使终止线程。

1. 使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。

2. 使用stop方法强行终止线程(线程中调用了阻塞代码)(这个方法不推荐使用,因为stop是依靠抛出异常来结束线程的,也可能发生不可预料的结果)。如果没有调用阻塞代码,可以正常结束线程。

3. 使用interrupt方法中断线程(线程中调用了阻塞代码)(其实这种方法也是通过抛出异常来结束线程的)。如果没有调用阻塞代码,可以通过判断线程的中断标志位来介绍线程。 线程的几个方法:

join():等待此线程死亡后再继续,可使异步线程变为同步线程

interrupt():中断线程,被中断线程会抛InterruptedException

wait():等待获取锁:表示等待获取某个锁执行了该方法的线程释放对象的锁,JVM会把该线程放到对象的等待池中。该线程等待其它线程唤醒

notify():执行该方法的线程唤醒在对象的等待池中等待的一个线程,JVM从对象的等待池中随机选择一个线程,把它转到对象的锁池中。使线程由阻塞队列进入就绪状态 sleep():让当前正在执行的线程休眠,有一个用法可以代替yield函数——sleep(0) yield():暂停当前正在执行的线程对象,并执行其他线程。也就是交出CPU一段时间(其他同样的优先级或者更高优先级的线程可以获取到运行的机会)

sleep和yield区别:

1、sleep()方法会给其他线程运行的机会,而不考虑其他线程的优先级,因此会给较低线程一个运行的机会;yield()方法只会给相同优先级或者更高优先级的线程一个运行的机会。

2、当线程执行了sleep(long millis)方法后,将转到阻塞状态,参数millis指定睡眠时间;当线程执行了yield()方法后,将转到就绪状态。

3、sleep()方法声明抛出InterruptedException异常,而yield()方法没有声明抛出任何异常

4、sleep()方法比yield()方法具有更好的移植性

如果希望明确地让一个线程给另外一个线程运行的机会,可以采取以下的办法之一:

1、调整各个线程的优先级

2、让处于运行状态的线程调用Thread.sleep()方法

3、让处于运行状态的线程调用Thread.yield()方法

4、让处于运行状态的线程调用另一个线程的join()方法

首先,wait()和notify(),notifyAll()是Object类的方法,sleep()和yield()是Thread类的方法。

(1).常用的wait方法有wait()和wait(long timeout):

void wait() 在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。

void wait(long timeout) 在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量前,导致当前线程等待。

wait()后,线程会释放掉它所占有的“锁标志”,从而使线程所在对象中的其它synchronized数据可被别的线程使用。

wait()和notify()因为会对对象的“锁标志”进行操作,所以它们必须在synchronized函数或synchronized代码块中进 行调用。如果在non- synchronized函数或

non-synchronized代码块中进行调用,虽然能编译通过,但在运 行时会发生

IllegalMonitorStateException的异常。

(2).Thread.sleep(long millis),必须带有一个时间参数。

sleep(long)使当前线程进入停滞状态,所以执行sleep()的线程在指定的时间内肯定不会被执行;

sleep(long)可使优先级低的线程得到执行的机会,当然也可以让同优先级和高优先级的线程有执行的机会;

sleep(long)是不会释放锁标志的。

(3).yield()没有参数。

sleep 方法使当前运行中的线程睡眼一段时间,进入不可运行状态,这段时间的长短是由程序设定的,yield 方法使当前线程让出CPU占有权,但让出的时间是不可设定的。yield()也不会释放锁标志。

实际上,yield()方法对应了如下操作: 先检测当前是否有相同优先级的线程处于同可运行状态,如有,则把 CPU 的占有权交给此线程,否则继续运行原来的线程。所以yield()方法称为“退让”,它把运行机会让给了同等优先级的其他线程。

sleep方法允许较低优先级的线程获得运行机会,但yield()方法执行时,当前线程仍处在可运行状态,所以不可能让出较低优先级的线程些时获得 CPU占有权。 在一个运行系统中,如果较高优先级的线程没有调用 sleep 方法,又没有受到 I/O阻塞,那么较低优先级线程只能等待所有较高优先级的线程运行结束,才有机会运行。

yield()只是使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。所以yield()只能使同优先级的线程有执行的机会。

volitile 语义

volatile相当于synchronized的弱实现,也就是说volatile实现了类似synchronized的语义,却又没有锁机制。它确保对volatile字段的更新以可预见的方式告知其他的线程。 volatile包含以下语义:

(1)Java 存储模型不会对valatile指令的操作进行重排序:这个保证对volatile变量的操作时按照指令的出现顺序执行的。

(2)volatile变量不会被缓存在寄存器中(只有拥有线程可见)或者其他对CPU不可见的地方,每次总是从主存中读取volatile变量的结 果。也就是说对于volatile变量的修改,其它线程总是可见的,并且不是使用自己线程栈内部的变量。也就是在happens-before法则中,对 一个valatile变量的写操作后,其后的任何读操作理解可见此写操作的结果。

尽管volatile变量的特性不错,但是volatile并不能保证线程安全的,也就是说volatile字段的操作不是原子性的,volatile变量只能保证可见性(一个线程修改后其它线程能够理解看到此变化后的结果),要想保证原子性,目前为止只能加锁!

数据同步:

线程同步的特征:

1、如果一个同步代码块和非同步代码块同时操作共享资源,仍然会造成对共享资源的竞争。因为当一个线程执行一个对象的同步代码块时,其他的线程仍然可以 执行对象的非同步代码块。(所谓的线程之间保持同步,是指不同的线程在执行同一个对象的同步代码块时,因为要获得对象的同步锁而互相牵制)

2、每个对象都有唯一的同步锁

3、在静态方法前面可以使用synchronized修饰符,但是要注意的是锁对象是类(用Object.class而不能用this),而不是这个类的对象。

4、当一个线程开始执行同步代码块时,并不意味着必须以不间断的方式运行,进入同步代码块的线程可以执行Thread.sleep()或者执行Thread.yield()方法,此时它并不释放对象锁,只是把运行的机会让给其他的线程。

5、synchronized声明不会被继承,如果一个用synchronized修饰的方法被子类覆盖,那么子类中这个方法不在保持同步,除非用synchronized修饰。

6、synchronized 关键字能够修饰一个对象实例中的函数或者代码块。 在一个非静态方法中 this 关键字表示当前的实例对象。 在一个 synchronized 修饰的静态的方法中,这个方法所在的类使用 Class 作为实例对象

更多相关推荐:
ERP总结报告--wangliheng

ERP综合实训报告一、实训概况ERP实训主要是通过沙盘推演和电脑模拟系统,来帮组大家了解企业的总体营运规则。在实训过程中,同一小组成员出任一家虚拟企业的高管层,通过分工和合作,对企业的生产、采购、财务、营销和投…

ERP总结

ERP沙盘模拟经营课程设计心得组ERP沙盘模拟经营心得经过激烈紧张的比赛,我们的ERP沙盘经营落下帷幕。在整个活动进程中我们小组的每个成员都是集思广益顾全大局各司其职的完成各自的职责,并且相互协助处理所遇到的涉…

erp总结

参加石河子大学erp总结参赛人员:参见了这次erp大赛让我们感到要想成功的经营一家公司起码要有以下几点1、战略意识:作为一名管理者,首先必须有战略意识。意见公司的生存和发展必须有方向、有目标,管理者的决策很大程…

ERP总结

ERP沙盘模拟总结宋卓男10244020工管1001班周日E组CEO短暂的ERP沙盘模拟结束了,作为周日E组的CEO,虽然我们获得了比赛的第一,可是其中有太多不足的地方,对于那些犯下得硬伤,身为CEO,我有不可…

ERP总结

ERP实验心得这个学期,学校开设了ERP(企业资源计划)的课程,通过老师的指导和自己的实际操作,对整个企业的运作和管理有了初步的了解,更重要的是学习了很多书本上没有的知识,为我们提供了一个实践操作的平台,实践能…

erp总结-财务总监助理

企业经营沙盘模拟总结报告公司编号:13职位:CFO助理姓名:沈昊宇班级:工商1003班学号:10245039前言:纠结的财务总监助理在这两个半天,六个年度,不,准确的说,只有五年的沙盘模拟中,我充分的体会到什么…

ERP总结

1.物料需求计划:①全重排式②净改变式特点:第一种方式从数据处理的角度看,效率比较高。但由于每次更新要间隔一定周期,通常至少也要一周,所以不能随时反映出系统的变化。第二种方式可以对系统进行频繁的,甚至是连续的更…

ERP总结coo

ERP沙盘总结沙盘是一种经营类的游戏,每一个小组代表一家公司或企业,进行模拟公司经营,每个组员都有着不同的工作职务。在本次沙盘游戏中,我所担任的职位是经营总监,经营总监这一职务所要做到的就是对公司未来经营的计划…

ERP总结

ERP沙盘模拟F组CEO总结在本次ERP沙盘模拟实验中,在听老师讲解了基本规则与步骤之后,经过小组的共同讨论,我担任了我们第一组的CEO角色。接下来简单说一下我们小组在进行六年模拟的一些基本情况:在刚开始第一年…

ERP总结

沙盘模拟训练总结上周在老师的带领下,我班顺利完成了本学期开启的必修课——ERP沙盘模拟训练教程。在短短六天的时间里,我从对ERP沙盘模拟一无所知到成为财务总监实际亲自进行各项工作,通过各项操作了解企业的经营管理…

茂名市中考满分作文-周辉ERP总结

ERP总结专业:物流管理班级:09物流五班姓名:周辉学号:0901100521职位:C组CEO在为期六天的ERP培训结束了,尽管时间不长,但在这个过程中使我对于企业运作,企业管理和经营方面有了一定的认识,对于C…

ERP总结报告

ERP沙盘实训总结报告学院:专业:学生姓名:学号:ERP(EnterrprsieResourcePlanning)是企业资源管理的简称,是针对物资资源管理(物流),人力资源管理(人流),财务资源管理(财流),信…

erp总结ppt(42篇)