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

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

3天内不再提示

Linux和Windows系统中的线程同步

星星科技指导员 来源:嵌入式计算设计 作者:Eduard Trunov 2022-11-30 15:13 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

介绍

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

在任何情况下组织多线程模型都需要同时访问相同的资源。本文提供有关 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

);

/* 成功完成时返回 0,出错时返回正值*/

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

在Windows中,线程是在_beginthread(ex)或CreateThread函数的帮助下创建的。两者都是运行时调用,它们之间的主要区别在于 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, in Windows:security– 指向结构的指针SECURITY_ATTRIBUTES,thrdaddr– 指向接收线程标识符的 32 位变量。

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

#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 threadn”);

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 threadn”);

return 0;

}

输出将如下所示:

Linux目录窗户

[root@localhost~]# 。/进程

来自主线程的你好

[root@localhost ~]#C:》进程.exe

来自主线程的你好

C:》

很容易注意到process_command_thread不是以可视方式运行的。当用于线程管理的内部结构由pthread_createor_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_joinWaitForSingleObject调用:

#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,本文介绍了由 POSIX.1-2001 标准(称为“pthreads”)定义的线程接口

本文稍后将介绍线程退出。

在此示例中,与本文中的其他示例一样,Linux 和 Windows 的代码库都是单一的。区别在于编译条件:

#ifdef __PL_WINDOWS__

//Windows code

#endif //__PL_WINDOWS__

#ifdef __PL_LINUX__

//Code for UNIX OS systems

#endif //__PL_LINUX__

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

    关注

    88

    文章

    11628

    浏览量

    217980
  • WINDOWS
    +关注

    关注

    4

    文章

    3697

    浏览量

    93232
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    Linux线程对比单线程的优势

    Linux系统线程是操作系统能够进行运算调度的最小单位。线程被包含在进程之中,是进程
    发表于 12-01 06:11

    WindowsLinux环境下分别使用Olimex和蜂鸟调试器下载程序

    程序时,可以使用Windows+Olimex+cmd的方式开发和运行程序。 在Windows/Linux系统下使用蜂鸟调试器时,可以按照官方quick start https
    发表于 10-31 08:26

    【HZ-T536开发板免费体验】—— linux创建线程

    自己的私有资源。 在linux系统线程状态通常反映了当前线程的当前活动和执行阶段。 主要分为: 1。运行转态 2。阻塞转态 3。终止状
    发表于 09-01 21:31

    WindowsLinux 系统切换:聚徽工控一体机的系统迁移避坑经验

    开源、稳定、安全等特性,在实时控制、嵌入式系统等领域备受青睐。然而,在实际应用,企业可能因业务需求变化、系统升级等原因,需要在 Windows
    的头像 发表于 06-24 16:09 579次阅读

    龙芯处理器支持WINDOWS吗?

    龙芯处理器目前不支持原生运行Windows操作系统,主要原因如下: 架构差异 龙芯架构:龙芯早期基于MIPS架构,后续转向自主研发的LoongArch指令集(与x86/ARM不兼容
    发表于 06-05 14:24

    聚徽厂家解码——工控机操作系统选择:WindowsLinux、QNX 如何匹配工业场景

    在工业自动化进程不断推进的当下,工控机作为核心设备,其操作系统的恰当选择对工业生产的稳定性、高效性和安全性起着决定性作用。常见的 WindowsLinux 和 QNX 操作系统,各自
    的头像 发表于 05-29 16:28 1244次阅读

    详解Linux系统的服务管理

    Linux,无论何时当你安装任何带有服务和守护进程的包,系统默认会把这些服务的初始化及 systemd脚本添加进去,不过此时它们并没有被启用。
    的头像 发表于 05-23 15:10 626次阅读
    详解<b class='flag-5'>Linux</b><b class='flag-5'>系统</b><b class='flag-5'>中</b>的服务管理

    不借助Linux系统,在Windows下如何搭建ZMC900E交叉编译环境

    不需要依赖笨重的虚拟机,也不需要安装双系统。抛开繁琐的环境准备,在Windows上轻松搭建交叉编译环境。本文将介绍如何在Windows上搭建交叉编译环境,不借助Linux
    的头像 发表于 05-21 11:34 650次阅读
    不借助<b class='flag-5'>Linux</b><b class='flag-5'>系统</b>,在<b class='flag-5'>Windows</b>下如何搭建ZMC900E交叉编译环境

    摩尔线程Linux驱动v3.0.0发布

    近日,摩尔线程正式推出Linux驱动程序v3.0.0,全面支持图形显卡MTT S80和高性能专业显卡MTT X300。作为v2.7.0RC4之后的重大升级版本,本次更新实现了多项关键技术突破:在架构
    的头像 发表于 05-08 11:38 1106次阅读
    摩尔<b class='flag-5'>线程</b><b class='flag-5'>Linux</b>驱动v3.0.0发布

    如何将FX3与WSL(LinuxWindows系统)一起使用?

    如何将 FX3 与 WSL(LinuxWindows系统)一起使用? 我在 /dev/ 找不到任何设备 我有许多项目在 Windows
    发表于 05-06 07:11

    Linux主要的性能有哪些?

      什么是Linux?   Linux是一套自由传播的类Unix操作系统,是一个基于posix和unix的多用户、多任务、支持多线程和多cpu的操作
    的头像 发表于 04-30 18:09 491次阅读
    <b class='flag-5'>Linux</b>主要的性能有哪些?

    如何实现Windows应用在Linux系统上的无缝运行

    统信 Windows 应用兼容引擎 V3.0 的推出,让用户可以在 deepin 系统上直接双击.exe文件运行 Windows 应用程序。 近期,我们收到了大家诸多的反馈信息。基于这些反馈,我们
    的头像 发表于 12-30 09:51 2535次阅读
    如何实现<b class='flag-5'>Windows</b>应用在<b class='flag-5'>Linux</b><b class='flag-5'>系统</b>上的无缝运行

    Ubuntu系统的优缺点分析 Ubuntu系统Windows的比较

    Ubuntu是一个基于Linux的开源操作系统,它以其稳定性、安全性和社区支持而闻名。以下是对Ubuntu系统优缺点的分析,以及与Windows系统
    的头像 发表于 12-12 14:31 5383次阅读

    如何在Windows安装Ubuntu系统

    Windows安装Ubuntu系统通常有两种方法:使用虚拟机软件安装Ubuntu作为虚拟机,或者使用双启动安装Ubuntu与Windows共存。以下是两种方法的步骤: 方法一:使用
    的头像 发表于 12-12 14:29 3168次阅读

    Hyper-V创建虚拟机配置IP等网络配置原理(LinuxWindows为例)

    大家知道Windows系统里面内置了Hyper-V管理器,用来创建和管理本地虚拟机环境。今天我创建了两台虚拟机,一台是CentOS7.9(Linux),另一台是Windows 11,然
    的头像 发表于 12-09 10:24 5585次阅读
    Hyper-V创建虚拟机配置IP等网络配置原理(<b class='flag-5'>Linux</b>、<b class='flag-5'>Windows</b>为例)