0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

关于Windows和Linux操作系统中线程同步了解

星星科技指导员 来源:嵌入式计算设计 作者:Eduard Trunov 2022-06-30 10:31 次阅读

介绍

在现代操作系统中,每个进程都有自己的地址空间和一个控制线程。然而,在实践中,我们经常遇到需要在单个进程中执行多个并发任务并访问相同进程组件的情况:结构、打开的文件描述符等。

在任何情况下组织多线程模型都需要同时访问相同的资源。本文提供了有关 Windows 和 Linux 操作系统中线程的一般信息,然后介绍了防止访问共享资源的同步机制[1] 。

对于那些处理从一个系统移植到另一个系统的应用程序或在一个系统中创建多线程应用程序并想知道它在另一个系统中如何实际实现的人来说,这篇文章将会很有趣。本文对于那些从未编写过多线程应用程序但计划在未来这样做的人也很有用。

线程概念

这些线程是做什么用的?为什么我们不能只创建流程?后一种范式已经工作了很多年,但是流程创建有一些缺点,下面举几个例子:

进程创建操作是资源密集型的。

进程需要复杂的机制来访问相同的资源(命名或未命名的管道、消息队列、套接字等),而线程会自动获得对相同地址空间的访问权。

多线程进程的性能高于单线程。

多线程允许多个线程作为一个进程的一部分执行。具有线程的编程模型为开发人员提供了对同时执行的舒适抽象。具有线程的程序的优点之一是它在具有多核处理器的计算机上运行得更快。线程在创建时几乎不使用资源,或者额外的插件,例如资源访问机制;此外,线程的性能和应用程序交互性更高。除了地址空间,所有线程都使用:

工艺规定

信号处理程序(处理信号的设置)

当前目录

用户和组标识符

同时,每个线程都有自己的:

线程标识符

寄存器

信号屏蔽

优先

使用线程的主要函数

在通过 exec 调用启动程序时,会创建一个主线程(初始线程)。辅助线程是通过调用 Linux 的 pthread_create 或 Windows 的 _beginthread(ex) 创建的。

让我们更仔细地看看 Linux 的线程创建:

#include

int pthread_create(

pthread_t *tid,

const pthread_attr_t *attr,

void *(*func)(void *),

void *arg

);

/* Returns 0 in case of a successful completion, positive value in case of an error*/

每个线程都有它的标识符——pthread_t——和属性:优先级、初始堆栈大小、守护进程特性。创建线程时,需要指明将要执行的函数地址(func),以及单指针参数(arg)。Linux 中的线程应显式退出——通过调用pthread_exit函数——或隐式退出——通过从该函数返回[2]。如果在问题的条件下需要将多个参数传递给线程,则必须使用带参数的结构地址。

在 Windows 中,线程是在_beginthread(ex)或CreateThread函数的帮助下创建的。两者都是 ?-runtime 调用,它们之间的主要区别在于CreateThread是一个“原始”Win32 API,而_beginthread(ex)在其内部调用CreateThread 。在本文中,我们将讨论_beginthread(ex)函数。_beginthreadex的语法如下:

uintptr_t _beginthreadex(

void *security,

unsigned stack_size,

unsigned(__stdcall *start_address)(void *),

void *arglist,

unsigned initflag,

unsigned *thrdaddr

);

可以观察到pthread_create和_beginthreadex调用之间有一些模糊的相似性;但是,也存在差异。?hus,在 Windows 中:security– 指向SECURITY_ATTRIBUTES结构的指针,thrdaddr– 指向接收线程标识符的 32 位变量。

让我们考虑以下线程创建示例:

#include

#ifdef __PL_WINDOWS__

#include

#endif //__PL_WINDOWS__

#ifdef __PL_LINUX__

#include

#endif //__PL_LINUX__

#define STACK_SIZE_IN_BYTES (2097152) //2MB

#ifdef __PL_WINDOWS__

unsigned int __stdcall process_command_thread(void) {

#endif //__PL_WINDOWS__

#if defined (__PL_LINUX__) || (__PL_SOLARIS__) || (__PL_MACOSX__)

void *process_command_thread(void *p) {

#endif //(__PL_LINUX__) || (__PL_SOLARIS__) || (__PL_MACOSX__)

printf("Hello from process command thread\n");

return 0;

}

int main(int argc, char *argv[])

{

#ifdef __PL_WINDOWS__

DWORD process_command_thread_id;

HANDLE h_process_command_thread;

h_process_command_thread = (HANDLE)_beginthreadex(

NULL,

STACK_SIZE_IN_BYTES,

process_command_thread,

NULL,

0,

(unsigned long *)&process_command_thread_id

);

if (h_process_command_thread == NULL)

return -1;

#endif //__PL_WINDOWS__

#ifdef __PL_LINUX__

pthread_t h_process_command_thread;

int h_process_command_thread_initialized;

int ret;

ret = pthread_create(

&h_process_command_thread,

NULL,

process_command_thread,

NULL

);

if (ret != 0)

return -1;

h_process_command_thread_initialized = 1;

#endif // __PL_LINUX__

printf("Hello from main thread\n");

return 0;

}

输出将如下:

pYYBAGK9CzCAR_3CAAAiMbNQdgM391.png

很容易注意到 process_command_thread 没有以可视方式运行。当用于线程管理的内部结构被pthread_create或_beginthreadex函数初始化时,主线程完成执行。在 Linux 中调用 pthread_join 后,我们可以期待线程退出。

int pthread_join(pthread_t tid, void **retval);

线程可以是可连接的(默认情况下)或分离的。当一个可连接线程终止时,信息(标识符、终止状态、线程计数器等)会一直保存到调用pthread_join为止。

在 Windows 操作系统中,可以认为等待函数之一类似于pthread_join。等待函数系列允许线程中断其执行并等待资源被释放。让我们看一下pthread_join的类似物,即WaitForSingleObject:

DWORD WaitForSingleObject(HANDLE hObject, DWORD dwMilliseconds);

调用此函数时,第一个参数hObject标识内核对象。该对象可能处于以下两种状态之一:“空闲”或“忙碌”。

第二个参数dwMilliseconds表示线程准备等待释放对象的毫秒数。

以下示例说明了pthread_join\WaitForSingleObject调用:

#ifdef __PL_WINDOWS__

DWORD status = WaitForSingleObject(

h_process_command_thread,

INFINITE

);

switch (status) {

case WAIT_OBJECT_0:

// The process terminated

break;

case WAIT_TIMEOUT:

// The process did not terminate within timeout

break;

case WAIT_FAILED:

// Bad call to function

break;

}

#endif //__PL_WINDOWS__

#ifdef __PL_LINUX__

int status = pthread_join(

h_process_command_thread,

NULL

);

switch (status) {

case 0:

// The process terminated

break;

case default:

// Bad call to function

break;

}

#endif //__PL_LINUX__

#ifdef __PL_WINDOWS__

//Windows code

#endif //__PL_WINDOWS__

#ifdef __PL_LINUX__

//Code for UNIX OS systems

#endif //__PL_LINUX__

审核编辑:郭婷

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Linux
    +关注

    关注

    87

    文章

    10981

    浏览量

    206689
  • WINDOWS
    +关注

    关注

    3

    文章

    3435

    浏览量

    87126
  • 操作系统
    +关注

    关注

    37

    文章

    6268

    浏览量

    121845
收藏 人收藏

    评论

    相关推荐

    服务器操作系统有几种?

    Linux、Unix等等,而人们常常应用的大部 分全是WindowsLinux系统软件。今日,小编就简单的给大伙儿介绍一下这两种常见的网络服务器电脑
    发表于 03-29 16:59

    linuxwindows的区别 linux系统一般用来干嘛

    LinuxWindows是两种不同的操作系统,有着不同的设计理念和用途。本文将对LinuxWindows的区别进行详细分析,并介绍
    的头像 发表于 02-05 14:06 310次阅读

    Linux操作系统中如何按下PCIe的复位键

    Linux操作系统中,看如何按下PCIe的复位键
    的头像 发表于 01-20 09:31 530次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>操作系统</b>中如何按下PCIe的复位键

    linuxwindows的区别

    闭源的,用户无法获取其源代码,因此对其内部机制的了解不够。 操作系统权限:Linux鼓励使用者去获取更多的权限,因为它没有严格的权限控制机制。而Windows则有较为严格的权限控制机制
    的头像 发表于 11-08 11:08 2326次阅读

    linux属于什么操作系统

    Linux属于一种类UNIX操作系统Linux,全称GNU/Linux,是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX
    的头像 发表于 11-08 11:01 1618次阅读

    开源操作系统大全

    开源操作系统即公开源代码的操作系统软件,它遵循开源协议使用、编译和发布。自由和开放源代码软件中最著名的是 Linux ,它是一种类 Unix 的操作系统
    发表于 10-27 15:13

    浅谈Linux操作系统的三大部分

    Linux操作系统是一种基于Unix的操作系统,它是由Linus Torvalds在1991年开发的。它是一个自由和开放源代码的操作系统,因此任何人都可以自由地使用、修改和发布它。
    发表于 07-23 12:59 1704次阅读
    浅谈<b class='flag-5'>Linux</b><b class='flag-5'>操作系统</b>的三大部分

    Linux线程编程基础知识解析

    线程是轻量级的进程(`LWP: Light Weight Process`),在`Linux`环境下线程的本质仍是`进程`,进程是资源分配的`最小单位`,线程
    发表于 07-14 16:41 468次阅读
    <b class='flag-5'>Linux</b>多<b class='flag-5'>线程</b>编程基础知识解析

    linux内核线程就这样诞生了么?

    线程操作系统的重要组成部件之一,linux内核中,内核线程是如何创建的,在内核启动过程中,诞生了哪些支撑整个系统运转的
    的头像 发表于 07-10 10:45 459次阅读
    <b class='flag-5'>linux</b>内核<b class='flag-5'>线程</b>就这样诞生了么?

    LinuxWindows服务器操作系统有什么区别?

    服务器管理员经常接触两种主要的操作系统,即LinuxWindows,那么,我们如何选择适合我们服务器的操作系统呢?当然,首先这两个操作系统
    的头像 发表于 06-01 15:52 980次阅读

    WindowsLinux同步机制4.6.2Linux父子进程同步(2)#操作系统

    操作系统
    学习硬声知识
    发布于 :2023年05月25日 18:17:48

    WindowsLinux同步机制4.6.2Linux父子进程同步(1)#操作系统

    操作系统
    学习硬声知识
    发布于 :2023年05月25日 18:16:56

    WindowsLinux同步机制4.6.1Windows同步机制(2)#操作系统

    操作系统
    学习硬声知识
    发布于 :2023年05月25日 18:16:04

    WindowsLinux同步机制4.6.1Windows同步机制(1)#操作系统

    操作系统
    学习硬声知识
    发布于 :2023年05月25日 18:15:29

    聊聊操作系统

    说到操作系统,大家都不会陌生。我们天天都在接触操作系统——用台式机或笔记本电脑,使用的是windows和macOS系统;用手机、平板电脑,则是android(安卓)和iOS
    的头像 发表于 05-12 11:13 1018次阅读
    聊聊<b class='flag-5'>操作系统</b>