一、实验目的
- (1)理解进程/线程的概念和应用编程过程;
- (2)理解进程/线程的同步机制和应用编程;
二、实验内容
- 1)在Linux下创建一对父子进程。
- 2)在Linux下创建2个线程A和B,循环输出数据或字符串。
- 3)在Windows下创建线程A和B,循环输出数据或字符串。
- 4)在Linux下创建一对父子进程,实验wait同步函数。
- 5)在Windows下利用线程实现并发画圆/画方。
- 6)在Windows或Linux下利用线程实现“生产者-消费者”同步控制
- 7)在Linux下利用信号机制实现进程通信。
- 8)在Windows或Linux下模拟哲学家就餐,提供死锁和非死锁解法。
三、实验要求
- 2,6,8必做,其余任选2。课前提前预做,老师机房检查和答疑
实验一,在Linux下创建一对父子进程。
- 提示 1:分别输出各自的进程号,父进程号和特别的提示字符串信息
- 提示 2:让父进程提前结束或后结束,观察子进程的父进程 ID。
- 提示 3:使用 PS 命令查看进程列表信息,核对进程号,父进程号
#include<unistd.h>
#include<stdio.h>
int main()
{
pid_t p1=fork();
if(p1>0){
printf(" 父进程进程号:%d\n",getpid());
printf(" 创建的子进程进程号:%d\n",p1);
printf(" 暂时挂起父进程以便ps检查结果(10s):\n");
sleep(2);
printf(" 父进程结束\n");
}else{
printf(" 子进程进程号:%d\n",getpid());
printf(" 父进程未结束时,子进程的父进程进程号:%d\n",getppid());
sleep(4);
printf(" \n父进程结束后,子进程的父进程进程号:%d\n",getppid());
printf(" 子进程结束\n");
}
return 0;
}
编译运行
gcc ./test.c -o test1.out
./test1.out
结果
使用 PS 命令查看进程列表信息,核对进程号,父进程号
ps -o pid,ppid,cmd
为什么没有./test1.out
我也不知道!!!毁灭吧!
ps -ef|grep test1.out
实验二,在Linux下创建2个线程A和B,循环输出数据或字符串
- 提示 1:使用 pthread 线程库
- 提示 2:线程 A 递增输出 1-1000;线程 B 递减输出 1000-1。为避免输出太快,每隔 0.2 秒(可自行调节)输出一个数。
- 提示 3:输出数据时,同时输出 A 或 B 以标示是哪个线程输出的,并注意格式化输出信息。
1.编写代码
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
//定义线程1运行函数
void* th_fn1(void *arg) //传入void*数值 a
{
for(int i=1;i<=1000;i++){
printf("A:%d\n",i);
sleep(1);
}
}
//定义线程2运行函数
void* th_fn2(void *arg) //传入void*数值 r
{
for(int i=1000;i>0;i--){
printf("B:%d\n",i);
sleep(1);
}
}
int main()
{
int err;//定义错误存储
pthread_t tid1,tid2;//定义线程标识符
//创建tid1线程
if(err=pthread_create(&tid1,NULL,th_fn1,NULL)){
perror("pthread_create error");
}
//创建tid2线程
if(err=pthread_create(&tid2,NULL,th_fn2,NULL)){
perror("pthread_create error");
}
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
return 0;
}
2.编译运行
注意要加入-lpthread
,才能使用线程。因为 pthread_create
等线程函数不在 C 标准库中。
gcc ./test2.c -o ./test2.out -lpthread
3.结果
实验三、在Windows下创建线程A和B,循环输出数据或字符串。
- 提示 1:使用 CreateThread 创建线程
- 提示 2:线程 A 递增输出 1-1000;线程 B 递减输出 1000-1。为避免输出太快,每隔 0.2 秒输出一个数。
- 提示 3:输出数据时,同时输出 A 或 B 标示是哪个线程输出的,并注意格式化输出信息
老师方法的代码
#include <iostream>
#include <thread>
#include <windows.h>
DWORD WINAPI add(LPVOID)
{
for (int i = 1; i<=1000; i++) {
std::cout << "A:" << i << std::endl;
Sleep(5);
}
return 1;
}
DWORD WINAPI dec(PVOID pParam) {
for (int i = 1000; i > 0; i--) {
std::cout << "B:" << i << std::endl;
Sleep(5);
}
return 0;
}
int main() {
HANDLE hthread[2];
DWORD threadID;
DWORD threadID1;
hthread[0] = CreateThread(NULL, 0, add, (LPVOID)1, 0, &threadID);
hthread[1] = CreateThread(NULL, 0, dec, (LPVOID)2, 0, &threadID1);
WaitForMultipleObjects(2, hthread, TRUE, INFINITE);
return 0;
}
运行结果
从 C++11 开始,线程,成为了 C++ 标准库的一部分,所以我们可以不再使用 CreateThread
来创建线程,简简单单地使用 std::thread
即可。
而且,CreateThread
是平台相关的,而 std::thread
是跨平台的。
因此,干嘛用CreateThread
。
使用std::thread
的代码
#include<iostream>
#include <thread>
void func_1() {
for (int i = 1; i <= 1000; i++) {
std::cout << i << std::endl;
}
}
void func_2() {
for (int i = 1000; i > 0; i--) {
std::cout << i << std::endl;
}
}
int main() {
std::thread t1(func_1);
std::thread t2(func_2);
t1.join();
t2.join();
return 0;
}
运行结果
实验六、在Windows或Linux下利用线程实现“生产者-消费者”同步控制
- 提示 1:使用数组(10 个元素)代替缓冲区。2 个输入线程产生产品(随机数)存到数组中;3 个输出线程从数组中取数输出。
- 提 示 2 : Windows 使 用 临 界 区 对 象 和 信 号 量 对 象 , 主 要 函 数EnterCriticalSection() 、 LeaveCriticalSection() 、 WaitForSingleObject() 、ReleaseSemaphore()。
- 提示 3:Linux 使用互斥锁对象和轻量级信号量对象,主要函数:sem_wait( ),sem_post( ),pthread_mutex_lock( ),pthread_mutex_unlock( )。
- 提示 4:生产者 1 的数据:1000-1999 (每个数据随机间隔 100ms-1s),生产者 2 的数据:2000-2999 (每个数据随机间隔 100ms-1s)。
- 提示 5:消费者每休眠 100ms-1s 的随机时间消费一个数据。
- 提示 6:屏幕打印(或日志文件记录)每个数据的生产和消费记录。
抄别人作业就好
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)