多线程编程实例
java多线程实际应用案例

java多线程实际应用案例Java多线程是一种并发编程的方式,可以使程序同时执行多个任务,提高程序的执行效率和响应速度。
下面列举了十个Java多线程实际应用案例。
1. 电商网站订单处理:在一个电商网站中,订单的处理是一个非常繁琐且耗时的工作,可以使用多线程实现订单的并发处理,提高订单处理的效率。
2. 聊天软件消息发送:在聊天软件中,用户发送消息是一个频繁的操作,可以使用多线程实现消息的并发发送,提高用户体验。
3. 数据库读写操作:在数据库的读写操作中,读操作可以使用多线程并发执行,提高数据的读取速度;写操作可以使用多线程并发执行,提高数据的写入速度。
4. 图像处理:在图像处理中,可以使用多线程实现图像的并行处理,提高图像处理的速度。
5. 视频编解码:在视频编解码中,可以使用多线程实现视频的并行编解码,提高视频的处理速度。
6. 网络爬虫:在网络爬虫中,可以使用多线程实现并发的爬取网页数据,提高爬虫的效率。
7. 游戏开发:在游戏开发中,可以使用多线程实现游戏的并行处理,提高游戏的运行速度和响应速度。
8. 大数据处理:在大数据处理中,可以使用多线程实现并发的数据处理,提高大数据处理的效率。
9. 并发服务器:在服务器开发中,可以使用多线程实现并发的请求处理,提高服务器的并发能力。
10. 并发任务调度:在任务调度中,可以使用多线程实现并发的任务执行,提高任务的执行效率。
在实际应用中,多线程不仅可以提高程序的执行效率和响应速度,还可以充分利用多核处理器的优势,实现并行计算和并发处理。
然而,多线程编程也面临着诸多挑战,如线程安全、死锁、资源竞争等问题,需要设计合理的线程同步和互斥机制,确保程序的正确性和稳定性。
因此,在使用多线程编程时,需要仔细考虑线程间的依赖关系和数据共享问题,合理规划线程的数量和调度策略,确保多线程程序的正确性和性能。
多线程编程实例---pthread_join函数详解1

多线程编程实例---pthread_join函数详解1单处理器上的linux多线程,是通过分时操作完成的;此时互斥锁的作用,只有在时间足够的情况下才能体现出来,即有时线程内需要延时;否则只有第一个线程不断解锁和获锁,别的线程在第一个线程执行完前无法获得互斥锁。
三pthread_join pthread_exit函数pthread_join用来等待一个线程的结束。
函数原型为:extern int pthread_join __P ((pthread_t __th, void **__thread_return));第一个参数为被等待的线程标识符,第二个参数为一个用户定义的指针,它可以用来存储被等待线程的返回值。
这个函数是一个线程阻塞的函数,调用它的函数将一直等待到被等待的线程结束为止,当函数返回时,被等待线程的资源被收回。
一个线程的结束有两种途径,一种是象我们上面的例子一样,函数结束了,调用它的线程也就结束了;另一种方式是通过函数pthread_exit来实现。
它的函数原型为:extern void pthread_exit __P ((void *__retval)) __attribute__ ((__noreturn__));唯一的参数是函数的返回代码,只要pthread_join中的第二个参数thread_return不是NULL,这个值将被传递给thread_return。
最后要说明的是,一个线程不能被多个线程等待,否则第一个接收到信号的线程成功返回,其余调用pthread_join的线程则返回错误代码ESRCH。
在这一节里,我们编写了一个最简单的线程,并掌握了最常用的三个函数pthread_create,pthread_join和pthread_exit。
下面,我们来了解线程的一些常用属性以及如何设置这些属性。
///////////////////////////////////////////////////////////////////////////源程序:/*thread_example.c : c multiple thread programming in linux*/#include#include#include#define MAX1 10#define MAX2 30pthread_t thread[2];pthread_mutex_t mut;int number=0, i;void *thread1(){printf ("thread1 : I'm thread 1\n");for (i = 0; i < MAX1; i++){printf("thread1 : number = %d i=%d\n",number,i);pthread_mutex_lock(&mut);number++;pthread_mutex_unlock(&mut);sleep(2);}printf("thread1 :Is main function waiting for me acomplishing task? \n");pthread_exit(NULL);}void *thread2(){printf("thread2 : I'm thread 2\n");for (i = 0; i < MAX2; i++){printf("thread2 : number = %d i=%d\n",number,i);pthread_mutex_lock(&mut);number++;pthread_mutex_unlock(&mut);sleep(3);}printf("thread2 :Is main function waiting for me to acomplish task ?\n");pthread_exit(NULL);}void thread_create(void){int temp;memset(&thread, 0, sizeof(thread)); //comment1/*创建线程*/if((temp = pthread_create(&thread[0], NULL, thread1, NULL)) != 0)printf("线程1创建失败!\n");elseprintf("Thread 1 is established\n");if((temp = pthread_create(&thread[1], NULL, thread2, NULL)) != 0) //comment3 printf("线程2创建失败");elseprintf("Thread 2 is established\n");}void thread_wait(void){/*等待线程结束*/if(thread[0] !=0) { //comment4pthread_join(thread[0],NULL);printf("Thread 1 is over \n");}if(thread[1] !=0) { //comment5pthread_join(thread[1],NULL);printf("Thread 2 is over\n");}}int main(){/*用默认属性初始化互斥锁*/pthread_mutex_init(&mut,NULL);printf("I am the main funtion,and I am establishing threads. Ha-ha\n");thread_create();printf("I am the main funtion,and I am waiting for thread to accomplish task. Ha-ha\n");thread_wait();return 0;}///////////////////////////////////////////////////////////执行情况1(linux终端):[root@localhost root]# gcc -o joint joint.c -lpthread[root@localhost root]# ./jointI am the main funtion,and I am establishing threads. Ha-hathread1 : I'm thread 1thread1 : number = 0 i=0Thread 1 is establishedthread2 : I'm thread 2thread2 : number = 1 i=0Thread 2 is establishedI am the main funtion,and I am waiting for thread to accomplish task. Ha-hathread1 : number = 2 i=1thread2 : number = 3 i=2thread1 : number = 4 i=3thread2 : number = 5 i=4thread1 : number = 6 i=5thread1 : number = 7 i=6thread2 : number = 8 i=7thread1 : number = 9 i=8thread2 : number = 10 i=9thread1 :Is main function waiting for me acomplishing task? Thread 1 is overthread2 : number = 11 i=11thread2 : number = 12 i=12thread2 : number = 13 i=13thread2 : number = 14 i=14thread2 : number = 15 i=15thread2 : number = 16 i=16thread2 : number = 17 i=17thread2 : number = 18 i=18thread2 : number = 19 i=19thread2 : number = 20 i=20thread2 : number = 21 i=21thread2 : number = 22 i=22thread2 : number = 23 i=23thread2 : number = 24 i=24thread2 : number = 25 i=25thread2 : number = 26 i=26thread2 : number = 27 i=27thread2 : number = 28 i=28thread2 : number = 29 i=29thread2 :Is main function waiting for me to acomplish task ? Thread 2 is over。
vc++2019 多线程编程例子

vc++2019 多线程编程例子当你在Visual Studio 2019中使用C++进行多线程编程时,你可以使用C++11标准中引入的`<thread>` 头文件来创建和管理线程。
以下是一个简单的例子,演示如何在VC++2019中使用多线程:```cpp#include <iostream>#include <thread>// 函数,将在新线程中运行void threadFunction(int id) {std::cout << "Thread " << id << " is running.\n";}int main() {// 启动三个线程std::thread t1(threadFunction, 1);std::thread t2(threadFunction, 2);std::thread t3(threadFunction, 3);// 等待线程完成t1.join();t2.join();t3.join();std::cout << "All threads have completed.\n";return 0;}```在这个例子中,`threadFunction` 函数将在新线程中运行,并且`main` 函数启动了三个不同的线程。
使用`join` 来等待线程的完成。
请确保在项目属性中的C++ 语言标准设置为C++11 或更高版本,以便支持`<thread>` 头文件。
在Visual Studio中,你可以通过右键单击项目,选择"属性",然后在"C/C++" -> "语言" 中设置"C++ 语言标准"。
记得在多线程编程中要小心处理共享资源,以避免竞态条件和其他并发问题。
c++ 多线程 future的get 例子

C++中的多线程是指程序同时执行多个线程的能力,可以有效地提高程序的运行效率。
在多线程编程中,future对象被用来获取异步操作的结果。
在C++中,future对象的get方法被用来获取异步操作的结果,本文将以实际例子介绍C++中多线程future的get使用方法。
1. 简介多线程和future对象多线程是指在一个程序中同时执行多个线程,每个线程都可以独立地执行任务。
多线程的优势在于可以提高程序的运行效率,特别是在进行大量计算或I/O密集型任务时。
在C++中,标准库提供了多线程的支持,包括thread、mutex、condition_variable等类和函数。
future对象是C++标准库提供的用来获取异步操作结果的机制。
通过future对象,我们可以异步执行一个任务,并在需要的时候获取任务的返回值。
future对象的get方法被用来获取异步操作的结果,但要注意的是,只有在任务执行完毕后才能调用get方法,否则程序会阻塞直到任务执行完毕。
2. 实例分析为了更好地理解C++中多线程future的get方法的使用,我们将通过一个实际的例子来进行说明。
假设我们有一个需求是计算一个数的阶乘,我们可以使用多线程来并行地计算多个数的阶乘,然后使用future对象的get方法来获取计算结果。
```#include <iostream>#include <future>#include <vector>unsigned long long factorial(unsigned int n) {if (n == 0)return 1;unsigned long long result = 1;for (unsigned int i = 1; i <= n; ++i)result *= i;return result;}int main() {std::vector<std::future<unsigned long long>> futures;std::vector<unsigned int> numbers = {5, 6, 7, 8, 9};for (unsigned int n : numbers) {futures.push_back(std::async(std::launch::async, factorial, n)); }for (std::future<unsigned long long> f : futures) {std::cout << "Factorial is " << f.get() << std::endl;}return 0;}```在上面的例子中,我们定义了一个factorial函数用来计算阶乘,然后在主函数中创建了多个future对象来异步执行这个计算任务。
Python3多线程菜鸟教程

Python3多线程菜鸟教程Python是一种非常常用的编程语言,与其它语言相比,Python具有简单易学、代码清晰、功能强大等优点。
在编写Python程序时,可以通过使用多线程来实现并发执行任务的目标。
本文将介绍Python3多线程的相关知识,并通过实例演示多线程的使用。
多线程是指在一个程序中同时执行多个线程。
每个线程都是独立的执行单元,可以进行不同的操作。
相比于单线程,多线程可以极大地提升程序的执行效率。
在Python中,可以使用threading模块来实现多线程。
通过创建Thread类的实例对象,可以创建并启动新的线程。
下面是一个简单的多线程示例:```pythonimport threadingdef function(:for i in range(5):print("线程执行中...")t = threading.Thread(target=function)t.startfor i in range(5):print("主线程执行中...")```多线程的另一个常见用途是进行并行计算。
当我们需要同时进行多个复杂的计算任务时,可以通过多线程来同时进行,从而提高计算效率。
除了使用threading模块,Python中还提供了concurrent.futures 模块来实现多线程。
concurrent.futures模块中的ThreadPoolExecutor 类可以用于创建线程池,从而更方便地管理和控制多个线程。
下面是一个使用ThreadPoolExecutor的示例代码:```pythonimport concurrent.futuresdef function(n):return n**2if __name__ == '__main__':with concurrent.futures.ThreadPoolExecutor( as executor:results = [executor.submit(function, i) for i in range(5)] print(future.result()```通过以上的示例代码,可以看到创建和管理多线程非常简单。
python的queue多线程实例

python的queue多线程实例Python 的queue 多线程实例多线程是一种并发编程的技术,它可以同时处理多个任务,提高程序的性能和效率。
在Python 中,使用多线程需要使用threading 模块。
而在进行多线程编程时,往往需要管理多个线程之间的任务分配和通信。
queue 是Python 提供的一个线程安全的队列,可以用于在多线程之间共享和传递数据。
本文将以使用queue 实现多线程任务分配和通信为主题,一步一步回答关于Python 的queue 多线程实例的问题。
1. 什么是queue?Queue 是Python 标准库中的一个模块,它提供了一个线程安全的队列,可以用于在多个线程之间安全地共享和传递数据。
Queue 实现了多线程之间的生产者-消费者模式,其中一个或多个线程充当生产者,将数据放入队列中,而另外一个或多个线程充当消费者,从队列中取出数据。
2. 如何使用queue 创建一个队列?使用queue 模块的Queue 类可以创建一个队列。
在创建队列时,可以指定队列的最大长度,如果不指定,默认为无限长。
下面是一个创建队列的示例代码:pythonfrom queue import Queue# 创建一个最大长度为10 的队列queue = Queue(maxsize=10)3. 如何向队列中添加数据?可以使用`put()` 方法向队列中添加数据。
`put()` 方法接收一个要添加的数据作为参数,并将数据放入队列。
下面是一个向队列中添加数据的示例代码:pythonqueue.put(1) # 添加整数1 到队列queue.put('Hello') # 添加字符串'Hello' 到队列4. 如何从队列中取出数据?可以使用`get()` 方法从队列中取出数据。
`get()` 方法将从队列中取出并返回一个数据。
下面是一个从队列中取出数据的示例代码:pythondata = queue.get() # 取出队列中的一个数据,并将其赋值给变量data5. 队列为空时如何处理?当队列为空时,使用`get()` 方法将会阻塞程序,直到队列中有数据可取。
linux下的CC++多进程多线程编程实例详解

linux下的CC++多进程多线程编程实例详解linux下的C\C++多进程多线程编程实例详解1、多进程编程#include <stdlib.h>#include <sys/types.h>#include <unistd.h>int main(){pid_t child_pid;/* 创建⼀个⼦进程 */child_pid = fork();if(child_pid == 0){printf("child pid\n");exit(0);}else{printf("father pid\n");sleep(60);}return 0;}2、多线程编程#include <stdio.h>#include <pthread.h>struct char_print_params{char character;int count;};void *char_print(void *parameters){struct char_print_params *p = (struct char_print_params *)parameters;int i;for(i = 0; i < p->count; i++){fputc(p->character,stderr);}return NULL;}int main(){pthread_t thread1_id;pthread_t thread2_id;struct char_print_params thread1_args;struct char_print_params thread2_args;thread1_args.character = 'x';thread1_args.count = 3000;pthread_create(&thread1_id, NULL, &char_print, &thread1_args);thread2_args.character = 'o';thread2_args.count = 2000;pthread_create(&thread2_id, NULL, &char_print, &thread2_args);pthread_join(thread1_id, NULL);pthread_join(thread2_id, NULL);return 0;}3、线程同步与互斥1)、互斥pthread_mutex_t mutex;pthread_mutex_init(&mutex, NULL);/*也可以⽤下⾯的⽅式初始化*/pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_lock(&mutex);/* 互斥 */thread_flag = value;pthread_mutex_unlock(&mutex);2)、条件变量int thread_flag = 0;pthread_mutex_t mutex;pthread_cond_t thread_flag_cv;\void init_flag(){pthread_mutex_init(&mutex, NULL);pthread_cond_init(&thread_flag_cv, NULL);thread_flag = 0;}void *thread_function(void *thread_flag){while(1){pthread_mutex_lock(&mutex);while(thread_flag != 0 ){pthread_cond_wait(&thread_flag_cv, &mutex);}pthread_mutex_unlock(&mutex);do_work();}return NULL;}void set_thread_flag(int flag_value){pthread_mutex_lock(&mutex);thread_flag = flag_value;pthread_cond_signal(&thread_flag_cv);pthread_mutex_unlock(&mutex);}感谢阅读,希望能帮助到⼤家,谢谢⼤家对本站的⽀持!。
java中实现多线程的方法

java中实现多线程的方法Java是一种非常强大的编程语言,它支持多线程,这是Java的一个重要特性。
多线程允许同时执行多个任务,从而大大提高了应用程序的效率和性能。
在Java中实现多线程的方法有很多种,下面我们将一步步地阐述这些方法。
第一种方法是继承Thread类。
我们可以在Java中创建一个继承Thread类的子类,并在子类中实现run()方法。
在run()方法中编写多线程代码。
以下是示例代码:```class MyThread extends Thread {public void run() {//多线程代码}}```在上述代码中,我们创建了一个名为MyThread的子类,并重写了Thread类的run()方法。
第二种方法是实现Runnable接口。
这种方法需要创建一个实现Runnable接口的类,然后实例化一个Thread对象并将实现Runnable 接口的类作为参数传递给Thread对象。
以下是示例代码:class MyRunnable implements Runnable {public void run() {//多线程代码}}public class Main {public static void main(String[] args) {MyRunnable obj = new MyRunnable();Thread thread = new Thread(obj);thread.start();}}```在上述代码中,我们创建了一个名为MyRunnable的类,并实现了Runnable接口。
我们在主类中创建了一个MyRunnable对象,并通过传递该对象作为参数创建了一个Thread对象。
最后启动线程。
第三种方法是使用匿名内部类。
这种方法可以减少代码的数量。
以下是示例代码:```public class Main {public static void main(String[] args) {new Thread(new Runnable() {public void run() {//多线程代码}}).start();}```在上述代码中,我们使用匿名内部类创建了一个Runnable对象并启动了一个线程。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
编写Linux下的多线程程序,需要使用头文件pthread.h,连接时需要使用库libpthread.a。
函数pthread_create用来创建一个线程,它的原型为:extern int pthread_create __P ((pthread_t *__thread, __const pthread_attr_t *__attr, void *(*__start_routine) (void *), void *__arg)); 第一个参数为指向线程标识符的指针,第二个参数用来设置线程属性,第三个参数是线程运行函数的起始地址,最后一个参数是运行函数的参数。
当创建线程成功时,函数返回0,若不为0则说明创建线程失败。
函数pthread_join用来等待一个线程的结束。
函数原型为:extern int pthread_join __P ((pthread_t __th, void **__thread_return)); 第一个参数为被等待的线程标识符,第二个参数为一个用户定义的指针,它可以用来存储被等待线程的返回值。
这个函数是一个线程阻塞的函数,调用它的函数将一直等待到被等待的线程结束为止,当函数返回时,被等待线程的资源被收回。
一个线程的结束有两种途径,一种是象我们上面的例子一样,函数结束了,调用它的线程也就结束了;另一种方式是通过函数pthread_exit来实现。
它的函数原型为:extern void pthread_exit __P ((void *__retval)) __attribute__ ((__noreturn__));最简单的线程程序:/* example.c*/#include <stdio.h>#include <pthread.h>void thread(void){int i;for(i=0;i<3;i++)printf("This is a pthread.\n");}int main(void){pthread_t id;int i,ret;ret=pthread_create(&id,NULL,(void *) thread,NULL);if(ret!=0){printf ("Create pthread error!\n");exit (1);}for(i=0;i<3;i++)printf("This is the main process.\n");pthread_join(id,NULL);return (0);}输出是什么样子?和进程相比,线程的最大优点之一是数据的共享性,各个进程共享父进程处沿袭的数据段,可以方便的获得、修改数据。
但这也给多线程编程带来了许多问题。
我们必须当心有多个不同的线程访问相同的变量。
许多函数是不可重入的,即同时不能运行一个函数的多个拷贝(除非使用不同的数据段)。
在函数中声明的静态变量常常带来问题,函数的返回值也会有问题。
因为如果返回的是函数内部静态声明的空间的地址,则在一个线程调用该函数得到地址后使用该地址指向的数据时,别的线程可能调用此函数并修改了这一段数据。
在进程中共享的变量必须用关键字volatile来定义,这是为了防止编译器在优化时(如gcc中使用-OX参数)改变它们的使用方式。
为了保护变量,我们必须使用信号量、互斥等方法来保证我们对变量的正确使用。
int square(volatile int *ptr){return *ptr * *ptr;}这个程序有什么错误?这段代码的目的是用来返指针*ptr指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器将产生类似下面的代码:int square(volatile int *ptr){int a,b;a = *ptr;b = *ptr;return a * b;}由于*ptr的值可能被意想不到地改变,因此a和b可能是不同的。
结果,这段代码可能返不是你所期望的平方值!正确的代码如下:long square(volatile int *ptr){int a;a = *ptr;return a * a;}互斥锁用来保证一段时间内只有一个线程在执行一段代码。
必要性显而易见:假设各个线程向同一个文件顺序写入数据,最后得到的结果一定是灾难性的。
下面一段代码是一个读/写程序,它们公用一个缓冲区,并且我们假定一个缓冲区只能保存一条信息。
即缓冲区只有两个状态:有信息或没有信息。
void reader_function ( void );void writer_function ( void );char buffer;int buffer_has_item=0;pthread_mutex_t mutex;struct timespec delay;void main ( void ){pthread_t reader;/* 定义延迟时间*/_sec = 2;_nec = 0;/* 用默认属性初始化一个互斥锁对象*/pthread_mutex_init (&mutex,NULL);pthread_create(&reader, pthread_attr_default, (void *)&reader_function), NULL);writer_function( );}void writer_function (void){while(1){/* 锁定互斥锁*/pthread_mutex_lock (&mutex);if (buffer_has_item==0){buffer=make_new_item( );buffer_has_item=1;}/* 打开互斥锁*/pthread_mutex_unlock(&mutex);pthread_delay_np(&delay);}}读操作如何实现?void reader_function(void){while(1){pthread_mutex_lock(&mutex);if(buffer_has_item==1){consume_item(buffer);buffer_has_item=0;}pthread_mutex_unlock(&mutex);pthread_delay_np(&delay);}}信号量被用来控制对公共资源的访问。
当公共资源增加时,调用函数sem_post()增加信号量。
只有当信号量值大于0时,才能使用公共资源,使用后,函数sem_wait()减少信号量。
下面我们逐个介绍和信号量有关的一些函数,它们都在头文件/usr/include/semaphore.h中定义。
P: ??V: ??信号量的数据类型为结构sem_t,它本质上是一个长整型的数。
函数sem_init()用来初始化一个信号量。
它的原型为:extern int sem_init __P ((sem_t *__sem, int __pshared, unsigned int __value));sem为指向信号量结构的一个指针;pshared不为0时此信号量在进程间共享,否则只能为当前进程的所有线程共享;value给出了信号量的初始值。
函数sem_post( sem_t *sem )用来增加信号量的值。
当有线程阻塞在这个信号量上时,调用这个函数会使其中的一个线程不在阻塞,选择机制同样是由线程的调度策略决定的。
函数sem_wait( sem_t *sem )被用来阻塞当前线程直到信号量sem的值大于0,解除阻塞后将sem的值减一,表明公共资源经使用后减少。
函数sem_destroy(sem_t *sem)用来释放信号量sem。
下面我们来看一个使用信号量的例子。
在这个例子中,一共有4个线程,其中两个线程负责从文件读取数据到公共的缓冲区,另两个线程从缓冲区读取数据作不同的处理(加和乘运算)。
/* File sem.c */#include <stdio.h>#include <pthread.h>#include <semaphore.h>#define MAXSTACK 100int stack[MAXSTACK][2];int size=0;sem_t sem;/* 从文件1.dat读取数据,每读一次,信号量加一*/ void ReadData1(void){FILE *fp=fopen("1.dat","r");while(!feof(fp)){fscanf(fp,"%d %d",&stack[size][0],&stack[size][1]);sem_post(&sem);++size;}fclose(fp);}/*从文件2.dat读取数据*/void ReadData2(void){FILE *fp=fopen("2.dat","r");while(!feof(fp)){fscanf(fp,"%d %d",&stack[size][0],&stack[size][1]);sem_post(&sem);++size;}fclose(fp);}/*阻塞等待缓冲区有数据,读取数据后,释放空间,继续等待*/void HandleData1(void){while(1){sem_wait(&sem);printf("Plus:%d+%d=%d\n",stack[size][0],stack[size][1],st ack[size][0]+stack[size][1]);--size;}}void HandleData2(void){while(1){sem_wait(&sem);printf("Multiply:%d*%d=%d\n",stack[size][0],stack[size][ 1],stack[size][0]*stack[size][1]);--size;}}int main(void){pthread_t t1,t2,t3,t4;sem_init(&sem,0,0);pthread_create(&t1,NULL,(void *)HandleData1,NULL);pthread_create(&t2,NULL,(void *)HandleData2,NULL);pthread_create(&t3,NULL,(void *)ReadData1,NULL);pthread_create(&t4,NULL,(void *)ReadData2,NULL);/* 防止程序过早退出,让它在此无限期等待*/pthread_join(t1,NULL);}生产者-消费者?使用pthread在线程之间实现。