继续完成操作系统原理的实验
4.3 (实验目的:熟悉Linux 创建线程的方法)在Ubuntu或Fedora环境使用pthread_create函数创建2个线程A和B。线程A在屏幕上用while循环顺序递增地输出1-1000的自然数;线程B在屏幕上用while循环顺序递减地输出1000-1之间的自然数。为避免输出太快,每隔0.5秒输出一个数。
4.4(实验目的:熟悉Window线程创建过程)Windows环境下,利用高级语言编程环境(限定为VS环境或VC环境)调用CreateThread函数实现4.3的功能。
4.1Window进程创建,4.2Linux fork创建进程–>操作系统原理实验二(一)
4.3Linux 创建线程
运行效果
代码展示
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>//sleep()需要的头文件
/* 声明结构体 */
struct member
{
int num;
char *name;
};
/* 定义线程pthread */
static void * pthread_1()
{
struct member *temp;
int num=1000;
while(num>=0)
{
printf("%d\n",num);
num--;
sleep(1);
}
}
static void * pthread_2()
{
struct member *temp;
int num=0;
while(num<=1000)
{
printf("%d\n",num);
num++;
sleep(1);
}
}
int main()
{
pthread_t tips_1;
pthread_t tips_2;
struct member *a,*b;
//为结构体变量a,b赋值
a=(struct member *)malloc(sizeof(struct member));
a->num=1;
a->name="first_thread";
b=(struct member *)malloc(sizeof(struct member));
b->num=2;
b->name="second_thread";
//创建线程
if((pthread_create(&tips_1,NULL,pthread_1,NULL))!=0)
{
fprintf(stderr,"thread_1 failed!");
exit(0);
}
if((pthread_create(&tips_2,NULL,pthread_2,NULL))!=0)
{
fprintf(stderr,"thread_2 failed!");
exit(0);
}
void *result1;
void *result2;
pthread_join(tips1, &result1);
pthread_join(tips2, &result2);
return 0;
}
解释一下
pthread_create函数介绍
头文件 #include<pthread.h>
函数声明
int pthread_create(pthread_t restrict tidp,const pthread_attr_t* restrict_attr,
void*(start_rtn)(void),void *restrict arg);
返回值:
若成功则返回0,否则返回出错编号
参数:第一个参数为指向线程标识符的指针。
第二个参数用来设置线程属性。
第三个参数是线程运行函数的地址。
最后一个参数是运行函数的参数。
注意
在编译时注意加上-lpthread参数,以调用静态链接库。因为pthread并非Linux系统的默认库。编译方式如下:
补充:开终端,运行C语言程序的语法
语法:命令gcc + c程序名 + -o +生成的可执行程序名
或者: 命令gcc + -o+生成的可执行程序名 + c程序名
然后再运行这个可执行程序 ./可执行程序名
thread_join函数
函数简介: 函数pthread_join用来等待一个线程的结束。
函数声明:
int pthread_join(
pthread_t __th,
void **__thread_return
);
参数:
第一个参数为被等待的线程标识符
第二个参数为一个用户定义的指针,它可以用来存储被等待线程的返回值
。
注意: 这个函数是一个线程阻塞的函数,调用它的函数将一直等待到被等待的线程结束为止,当函数返回时,被等待线程的资源被收回。如果执行成功,将返回0,如果失败则返回一个错误号。
另外注意一下,在Linux中sleep(int),括号里面的值单位为秒, 即sleep(1)为暂停1秒跟Windows下有所不同
4.4Windows 创建线程
运行效果
代码展示
#include<stdio.h>
#include<Windows.h>
//定义线程
DWORD WINAPI pthread_1(LPVOID)
{
printf("我是子线程_1, pid = %d\n", GetCurrentThreadId()); //输出子线程pid
int num = 1000;
while (num>=0)
{
printf("%d\n", num);
num--;
Sleep(500);
}
return 0;
}
DWORD WINAPI pthread_2(LPVOID)
{
printf("我是子线程_2, pid = %d\n", GetCurrentThreadId()); //输出子线程pid
int num = 0;
while (num <= 1000)
{
printf("%d\n", num);
num++;
Sleep(500);
}
return 0;
}
int main()
{
HANDLE hThread[2];//记录新线程句柄
DWORD threadID;//记录线程ID
//参数:继承/初始栈大小/线程函数/向线程传递的参数/线程标志 0表示创建后立即激活/保存新线程的ID
if ((hThread[0] = CreateThread(NULL, 0, pthread_1, 0, 0, &threadID))==NULL)
{
printf("子线程_1创建失败!");
}
if ((hThread[1] = CreateThread(NULL, 0, pthread_2, 0, 0, &threadID)) == NULL)
{
printf("子线程_2创建失败!");
}
//等待所有线程结束
WaitForMultipleObjects(2, hThread, TRUE, INFINITE);
CloseHandle(hThread[0]);
CloseHandle(hThread[1]);
return 0;
}
函数原型:
HANDLE WINAPI CreateThread(
In_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
In SIZE_T dwStackSize,
In LPTHREAD_START_ROUTINE lpStartAddress,
In_opt LPVOID lpParameter,
In DWORD dwCreationFlags,
Out_opt LPDWORD lpThreadId
);
- 参数说明:
第一个参数 lpThreadAttributes 表示线程内核对象的安全属性,一般传入NULL表示使用默认设置。
第二个参数 dwStackSize 表示线程栈空间大小。传入0表示使用默认大小(1MB)。
第三个参数 lpStartAddress 表示新线程所执行的线程函数地址,多个线程可以使用同一个函数地址。
第四个参数 lpParameter 是传给线程函数的参数。
第五个参数 dwCreationFlags 指定额外的标志来控制线程的创建,为0表示线程创建之后立即就可以进行调度,如果为CREATE_SUSPENDED则表示线程创建后暂停运行,这样它就无法调度,直到调用ResumeThread()。
第六个参数 lpThreadId 将返回线程的ID号,传入NULL表示不需要返回该线程ID号。
3.返回值 线程创建成功返回新线程的句柄,失败返回NULL
我只是理论的搬运工hhhh
附参考链接:windows多线程(一) 创建线程 CreateThread
写在结尾
希望以上可以帮到你!
如有错误,或不同想法,欢迎指出,互相学习共同进步!