当前位置: 首页 > news >正文

POSIX 信号量(Semaphore)


一、POSIX 信号量基础

1. 什么是信号量?
  • 信号量 是一种同步机制,用于控制对共享资源的访问。它通过一个整数值表示可用资源的数量,支持两种原子操作:
    • P操作(Wait):尝试减少信号量值(若值>0,则减1;否则阻塞)。
    • V操作(Post):增加信号量值(唤醒等待的线程/进程)。
2. POSIX 信号量的两种类型
类型应用场景特点
命名信号量进程间同步通过文件名全局标识
未命名信号量线程间同步(或进程内)需通过共享内存传递

二、命名信号量(进程间同步)

1. 核心函数
  • sem_open():创建或打开命名信号量
  • sem_wait():P操作(阻塞)
  • sem_post():V操作(释放)
  • sem_close():关闭信号量
  • sem_unlink():销毁信号量
2. 示例:两个进程同步访问文件

进程A(写入数据)

#include <fcntl.h>
#include <semaphore.h>
#include <stdio.h>int main() {sem_t *sem = sem_open("/my_named_sem", O_CREAT, 0666, 1); // 初始值为1if (sem == SEM_FAILED) {perror("sem_open failed");return -1;}sem_wait(sem); // 获取信号量(P操作)FILE *fp = fopen("shared.txt", "a");fprintf(fp, "Process A writes.\n");fclose(fp);sem_post(sem); // 释放信号量(V操作)sem_close(sem);sem_unlink("/my_named_sem"); // 注意:仅在最后一个进程调用后销毁return 0;
}

进程B(读取数据)

sem_t *sem = sem_open("/my_named_sem", 0); // 打开已有信号量
sem_wait(sem);
FILE *fp = fopen("shared.txt", "r");
char buf[100];
fgets(buf, 100, fp);
printf("Read: %s", buf);
fclose(fp);
sem_post(sem);
sem_close(sem);

三、未命名信号量(线程间同步)

1. 核心函数
  • sem_init():初始化信号量(需指定线程共享标志)
  • sem_destroy():销毁信号量
2. 示例:多线程任务池
#include <pthread.h>
#include <semaphore.h>
#define MAX_TASKS 5sem_t task_sem; // 未命名信号量
int task_queue[MAX_TASKS];
int task_count = 0;void* worker_thread(void* arg) {while (1) {sem_wait(&task_sem); // 等待任务// 取出任务并处理int task = task_queue[--task_count];printf("Processing task: %d\n", task);}return NULL;
}void add_task(int task) {task_queue[task_count++] = task;sem_post(&task_sem); // 发布新任务
}int main() {sem_init(&task_sem, 0, 0); // 初始值为0(无任务)pthread_t tid;pthread_create(&tid, NULL, worker_thread, NULL);// 添加任务for (int i = 0; i < 10; i++) {add_task(i);sleep(1);}sem_destroy(&task_sem);return 0;
}

四、关键注意事项

1. 信号量 vs 互斥锁
特性信号量互斥锁
资源数量可设置初始值(N个资源)仅1(互斥)
所有者无所有者概念锁定者必须负责解锁
跨进程支持(命名信号量)需进程共享的互斥锁
2. 常见陷阱
  • 死锁:多个信号量未按顺序获取。
    • 解决:统一资源申请顺序。
  • 资源泄漏:未正确调用 sem_close()sem_unlink()
    • 命名信号量会残留于 /dev/shm(Linux)。
  • 虚假唤醒sem_wait() 可能被信号中断。
    • 建议配合循环检查实际条件。

五、高级应用场景

1. 有限资源池(如数据库连接)
sem_t db_conn_sem;
sem_init(&db_conn_sem, 0, 10); // 最多10个连接void query_database() {sem_wait(&db_conn_sem); // 获取连接// 执行查询...sem_post(&db_conn_sem); // 释放连接
}
2. 多进程生产者-消费者
// 共享内存中定义循环队列和信号量
struct {int buffer[BUFFER_SIZE];int in, out;sem_t empty, full;
} *shared;// 生产者进程
sem_wait(&shared->empty);
shared->buffer[shared->in] = data;
shared->in = (shared->in + 1) % BUFFER_SIZE;
sem_post(&shared->full);// 消费者进程
sem_wait(&shared->full);
data = shared->buffer[shared->out];
shared->out = (shared->out + 1) % BUFFER_SIZE;
sem_post(&shared->empty);

六、代码实战:跨进程聊天程序

1. 设计思路
  • 使用 命名信号量 控制消息队列的访问。
  • 共享内存存储消息缓冲区。
  • 两个进程交替发送和接收消息。
2. 核心代码片段
// 共享内存结构
struct chat_buffer {char message[256];sem_t send_sem, recv_sem;
};// 进程A(先发送)
struct chat_buffer *buf = mmap(...);
sem_init(&buf->send_sem, 1, 1);  // 初始可发送
sem_init(&buf->recv_sem, 1, 0);  // 初始不可接收while (1) {sem_wait(&buf->send_sem);fgets(buf->message, 256, stdin);sem_post(&buf->recv_sem);
}// 进程B(先接收)
sem_wait(&buf->recv_sem);
printf("Received: %s", buf->message);
sem_post(&buf->send_sem);

七、总结

  • POSIX 信号量 是强大的同步工具,适用于线程和进程间的复杂协调。
  • 命名信号量 通过文件系统标识,适合进程间同步。
  • 未命名信号量 更轻量,但需手动管理内存共享。
  • 始终注意 资源释放死锁预防,结合日志或调试工具验证同步逻辑。

相关文章:

POSIX 信号量(Semaphore)

一、POSIX 信号量基础 1. 什么是信号量&#xff1f; 信号量 是一种同步机制&#xff0c;用于控制对共享资源的访问。它通过一个整数值表示可用资源的数量&#xff0c;支持两种原子操作&#xff1a; P操作&#xff08;Wait&#xff09;&#xff1a;尝试减少信号量值&#xff0…...

深度学习驱动下的字符识别:挑战与创新

一、引言 1.1 研究背景 深度学习在字符识别领域具有至关重要的地位。随着信息技术的飞速发展&#xff0c;对字符识别的准确性和效率要求越来越高。字符识别作为计算机视觉领域的一个重要研究方向&#xff0c;其主要目的是将各种形式的字符转换成计算机可识别的文本信息。近年…...

DOM TreeWalker API 详解

DOM TreeWalker API 详解 TreeWalker API 是 DOM 中一个强大但相对较少使用的功能&#xff0c;它提供了一种有效遍历文档树的方式。它比手动递归或使用简单的节点导航方法更加灵活和高效。 TreeWalker 基本概念 TreeWalker 对象可以让你按照指定的过滤条件&#xff0c;以特定…...

深度学习| Deep Snake环境配置+训练+预测评估(超全面)

前言:Deep Snake是一个比较经典结合了轮廓的深度学习分割方法,但是去实际运行Deep Snake项目的时候遇到了很多问题。这篇文章把Deep Snake从环境配置、训练到预测评估,都做了详细的教程,还补充了一些相关的知识点。 Deep Snake配置和运行 Deep Snake信息数据集COCOMask-&g…...

NHANES指标推荐:CMI

文章题目&#xff1a;Association between cardiometabolic index and biological ageing among adults: a population-based study DOI&#xff1a;10.1186/s12889-025-22053-3 中文标题&#xff1a;成年人心脏代谢指数与生物衰老之间的关系&#xff1a;一项基于人群的研究 发…...

非比较排序——计数排序

计数排序 计数排序是非比较排序 void CountSort(int *a,int n) {//找范围int mina[0],maxa[0];for(int i0;i<n;i){if(a[i]<min){mina[i];}if(a[i]>max){mina[i];}}int rangemax-min1;//创建计数用的数组int *count(int *) malloc(range* sizeof(int));//计数数组的元…...

spring cloud gateway前面是否必须要有个nginx

在 **"客户端 → Nginx (前置限流) → Spring Cloud Gateway → 微服务(Sentinel 熔断限流)"** 的架构中&#xff0c;**Spring Cloud Gateway 前面并不强制要求必须有 Nginx**&#xff0c;是否需要取决于具体场景。以下是详细分析&#xff1a; 一、必须使用 Nginx 的…...

复现SCI图像增强(Toward fast, flexible, and robust low-light image enhancement.)

运行train.py报错 > File "/home/uriky/桌面/SCI-main/SCI-main/train.py", line 105, in main > train_queue torch.utils.data.DataLoader( File "/home/uriky/anaconda3/envs/AA/lib/python3.8/site-packages/torch/utils/data/dataloader.py&q…...

Linux 进程

文章目录 1. 冯诺依曼体系结构1.1 什么是冯诺依曼体系结构1.2 为什么选择冯诺依曼结构 2. 操作系统2.1 操作系统是什么2.2 操作系统如何对硬件资源进行管理2.3 计算机的层状体系结构 3. 进程3.1 进程是什么3.2 进程的相关属性3.3 在Linux中了解进程3.3.1 查看进程3.3.2 子进程由…...

TVM计算图分割--Collage

1 背景 为满足高效部署的需要&#xff0c;整合大量优化的tensor代数库和运行时做为后端成为必要之举。现在的深度学习后端可以分为两类&#xff1a;1&#xff09;算子库(operator kernel libraries)&#xff0c;为每个DL算子单独提供高效地低阶kernel实现。这些库一般也支持算…...

Liunx知识点

1./dev&#xff1a;是系统设备文件存放位置 /home&#xff1a;是普通用户存放目录 /etc&#xff1a;大部分配置文件的存放目录 /mnt&#xff1a;挂载服务需要的目录 /tmp&#xff1a;存放临时文件 /boot&#xff1a;启动文件 /root&#xff1a;root用户存放目录 /var&am…...

全栈架构设计图

以下是针对Vue前端、服务端、管理后台及数据库的架构图和交互流程设计&#xff0c;采用分层结构和模块化设计思路&#xff1a; 一、系统整体架构图 #mermaid-svg-vAtZ3R6d5Ujm6lYT {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}…...

【SAP ME 42】SAP ME 性能改进

性能问题症状 可观察到以下症状:com.sap.me.production$SfcStartService#startSfc - 此 API 方法具有来自 RESOURCE_TYPE_RESOURCE 表的 SQL 查询的运行速度较慢。 com.sap.me.production$CreateSfcService#createSfc - 对于每个创建的车间作业控制,检查在计划标准配置中是否…...

《GPT-4.1深度解析:AI进化新标杆,如何重塑行业未来?》

一、GPT-4.1:AI 领域的 “全能战士” 降临 1.1 发布背景与战略意义 在 OpenAI 的技术迭代版图中,GPT-4.1 被赋予了 “承前启后” 的关键角色。它不仅是 GPT-4o 的全面升级版,更被视为向 GPT-5 过渡的重要桥梁。2025 年 4 月 15 日的发布会上,OpenAI 宣布 GPT-4.1 系列模型…...

node.js 基础

模块导入和导出 形式1 function get_jenkins(){return "jenkins....." }function test_cc(){return "4444444" }export {get_jenkins,test_cc}// 主函数 import { get_jenkins, test_cc } from ./module.js;console.log(get_jenkins()); console.log(tes…...

数据结构中的宝藏秘籍之广义表

广义表&#xff0c;也被称作列表&#xff08;Lists&#xff09;&#xff0c;是一种递归的数据结构。它就像一个神秘的盒子&#xff0c;既可以装着单个元素&#xff08;原子&#xff09;&#xff0c;也可以嵌套着其他的盒子&#xff08;子列表&#xff09;。比如广义表 (a (b c)…...

电流模式控制学习

电流模式控制 电流模式控制&#xff08;CMC&#xff09;是开关电源中广泛使用的一种控制策略&#xff0c;其核心思想是通过内环电流反馈和外环电压反馈共同调节占空比。相比电压模式控制&#xff0c;CMC具有更快的动态响应和更好的稳定性&#xff0c;但也存在一些固有缺点。 …...

汽车免拆诊断案例 | 2011款雪铁龙世嘉车刮水器偶尔自动工作

故障现象 一辆2011款雪铁龙世嘉车&#xff0c;搭载1.6 L 发动机&#xff0c;累计行驶里程约为19.8万km。车主反映&#xff0c;该车刮水器偶尔会自动工作&#xff0c;且前照灯偶尔会自动点亮。 故障诊断 接车后试车发现&#xff0c;除了上述故障现象以外&#xff0c;当用遥控器…...

#去除知乎中“盐选”付费故事

添加油猴脚本&#xff0c;去除知乎中“盐选”付费故事 // UserScript // name 盐选内容隐藏脚本 // namespace http://tampermonkey.net/ // version 0.2 // description 自动隐藏含有“盐选专栏”或“盐选”文字的回答卡片 // author YourName // mat…...

github 项目迁移到 gitee

1. 查看远程仓库地址 git remote -v 2. 修改远程仓库地址 确保 origin 指向你的 Gitee 仓库&#xff0c;如果不是&#xff0c;修改远程地址。 git remote set-url origin https://gitee.com/***/project.git 3. 查看本地分支 git branch 4. 推送所有本地分支 git p…...

2025年03月中国电子学会青少年软件编程(Python)等级考试试卷(五级)答案 + 解析

青少年软件编程(Python)等级考试试卷(五级) 分数:100 题数:38 一、单选题(共25题,共50分) 1. 以下哪个选项不是Python中的推导式?( ) A. 列表推导式 B. 字典推导式 C. 集合推导式 D. 元组推导式 正确答案:D 答案解析:Python中的推导式包括列表推导式、字典推导式…...

[Unity]-[UI]-[Prefab] 关于UGUI UI Prefab的制作技巧

从上到下&#xff0c;从外到里&#xff0c;多用空物体套壳 这个意思就是说在使用ugui时制作prefab时&#xff0c;要遵循“从上到下&#xff0c;从外到里&#xff0c;多用空物体套壳”的原则&#xff0c;好处就是后面好修改&#xff0c;并且可以复用不同的prefab子模块。且在布…...

【Reading Notes】(8.3)Favorite Articles from 2025 March

【March】 雷军一度登顶中国首富&#xff0c;太厉害了&#xff08;2025年03月02日&#xff09; 早盘&#xff0c;小米港股一路高歌猛进&#xff0c;暴涨4%&#xff0c;股价直接飙到52港元的历史新高。这一波猛如虎的操作&#xff0c;直接把雷军的身家拉到了2980亿元&#xff0c…...

2021-11-09 C++倍数11各位和为13

缘由c函数题找数字的-编程语言-CSDN问答 void 倍数11各位和为13(int n, int& b, int* h) {//缘由https://ask.csdn.net/questions/7559803?spm1005.2025.3001.5141b !(n % 11);while(n)*h n % 10, n / 10; }int a 1, b 1, c 0, d 0;while (a < 100){倍数11各位和…...

2025年03月中国电子学会青少年软件编程(Python)等级考试试卷(六级)真题

青少年软件编程&#xff08;Python&#xff09;等级考试试卷&#xff08;六级&#xff09; 分数&#xff1a;100 题数&#xff1a;38 答案解析&#xff1a;https://blog.csdn.net/qq_33897084/article/details/147341458 一、单选题(共25题&#xff0c;共50分) 1. 在tkinter的…...

Linux简介

一、Linux 简介 Linux 内核最初只是由芬兰人林纳斯托瓦兹&#xff08;Linus Torvalds&#xff09;在赫尔辛基大学上学时出于个人爱好而编写的。 Linux 是一套免费使用和自由传播的类 Unix 操作系统&#xff0c;是一个基于 POSIX 和 UNIX 的多用户、多任务、支持多线程和多 CP…...

每天学一个 Linux 命令(22):pwd

​​可访问网站查看,视觉品味拉满: http://www.616vip.cn/22/index.html pwd 命令用于打印当前工作目录(Print Working Directory)的绝对路径,帮助用户快速确认自己在文件系统中的位置。虽然简单,但它是终端操作中不可或缺的基础命令,尤其在处理相对路径或脚本编写时尤为…...

Windows 11设置开机自动运行 .jar 文件

Windows 11设置开机自动运行 .jar 文件 打开启动文件夹&#xff1a; 按下 Win R&#xff0c;输入 shell:startup&#xff0c;回车。 此路径为当前用户的启动文件夹&#xff1a; C:\Users\<用户名>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup创…...

西门子 博途 软件 崩溃

西门子 博途 软件 编译/仿真 崩溃 是因为项目中OPC UA的接口问题 解决拌饭见 https://support.industry.siemens.com/cs/document/109971630/tia-portal-%E5%9C%A8%E7%BC%96%E8%AF%91-plc-%E6%97%B6%E5%B4%A9%E6%BA%83?dti0&dlzh&lcen-WW...

12芯束装光纤不同包层线颜色之间的排列顺序

为什么光纤线必须按照以下颜色顺序进行排序&#xff1f;这其实是为了防止光污染的问题&#xff0c;不同颜色在传递光时从包层表皮漏光传感到梳妆的其它纤芯上&#xff0c;会有光污染的问题&#xff0c;而为了减少并防止光污染的现象&#xff0c;所以在光通信之中&#xff0c;需…...

数据驱动、精准协同:高端装备制造业三位一体生产管控体系构建

开篇引入 鉴于集团全面推行生产运营体建设以及对二级单位生产过程管控力度逐步加强&#xff0c;某高端装备制造企业生产部长王总正在开展新的一年企业生产管控规划工作&#xff0c;为了能够更好地进行体系规划与建设应用&#xff0c;特邀请智能制造专家小智来进行讨论交流。 王…...

HAL详解

一、直通式HAL 这里使用一个案例来介绍直通式HAL&#xff0c;选择MTK的NFC HIDL 1.0为例&#xff0c;因为比较简单&#xff0c;代码量也比较小&#xff0c;其源码路径&#xff1a;vendor/hardware/interfaces/nfc/1.0/ 1、NFC HAL的定义 1&#xff09;NFC HAL数据类型 通常定…...

RAG知识库中引入MCP

MCP(Memory, Context, Planning)是一种增强AI系统认知能力的框架。将MCP引入RAG知识库可以显著提升系统的性能和用户体验。下面我将详细介绍如何实现这一整合。 MCP框架概述 MCP框架包含三个核心组件: Memory(记忆):存储和管理历史交互和知识Context(上下文):理解当…...

再读bert(Bidirectional Encoder Representations from Transformers)

再读 BERT&#xff0c;仿佛在数字丛林中邂逅一位古老而智慧的先知。初次相见时&#xff0c;惊叹于它以 Transformer 架构为罗盘&#xff0c;在预训练与微调的星河中精准导航&#xff0c;打破 NLP 领域长久以来的迷雾。而如今&#xff0c;书页间跃动的不再仅是 Attention 机制精…...

C# 单例模式

创建一个类 在类中定义方法 internal class Config {// 实现单利模式private static Config instance null;private Config() { }private static object Locker new object(); // 定义lock锁// 通过公有的方法 返回实力public static Config GetInstance(){// 空的自己构造…...

mainwidget.cpp:1741:21: error: use of undeclared identifier ‘mainTab‘

这个错误表明在你的代码中&#xff0c;mainTab 这个变量没有被正确声明或定义。这通常是因为以下原因之一&#xff1a; 变量未声明&#xff1a;mainTab 可能没有在类的成员变量中声明。 变量未初始化&#xff1a;mainTab 可能没有在构造函数中正确初始化。 作用域问题&#x…...

OpenCV day6

函数内容接上文&#xff1a;OpenCV day4-CSDN博客 , OpenCV day5-CSDN博客 目录 平滑&#xff08;模糊&#xff09; 25.cv2.blur()&#xff1a; 26.cv2.boxFilter(): 27.cv2.GaussianBlur()&#xff1a; 28.cv2.medianBlur(): 29.cv2.bilateralFilter()&#xff1a; 锐…...

MySQL:Join连接的原理

连接查询的执行过程&#xff1a; 确定第一个需要查询的表【驱动表】 选取代价最小的访问方法去执行单表查询语句 从驱动表每获取到一条记录&#xff0c;都需要到t2表中查找匹配的记录 两表连接查询需要查询一次t1表&#xff0c;两次t2表&#xff0c;在两表的连接查询中&…...

Linux MySQL版本升级(rpm安装方式)

一、背景 近期生产环境扫描发现MySQL的多个安全漏洞。目前厂商已经发布了升级补丁以修复此安全问题&#xff0c;补丁获取链接&#xff1a;https://www.oracle.com/security-alerts/cpuoct2024.html 二、升级注意事项 备份数据&#xff1a;升级前务必备份数据库。检查兼容性&…...

数字图像处理(膨胀与腐蚀)

腐蚀 核心原理&#xff1a;结构元四肢运算结果全为1&#xff0c;则结构元中心为1&#xff0c;否则为0。 怎么计算是否为1还是为0 结构元的值与前景的值进行与运算&#xff0c;如果结构元四肢的与运算结果全为1&#xff0c;则结构元中心为1&#xff0c;否则为0。 假设下图为结构…...

J值即正义——Policy Gradient思想、REINFORCE算法,以及贪吃蛇小游戏(三)

文章目录 前情提要谁的J值大呢?那么 ∇ θ J ( θ ) \nabla_\theta J(\theta) ∇θ​J(θ)要怎么求呢?构建loss函数**代码实现示例**(PyTorch伪代码):前情提要 上回咱说道,对于强化学习而言,J值即正义。 比如,你当了老板,你手下的两个高管,分别都为公司的发展提出了…...

pdfjs库使用3

.App { text-align: center; height: 100vh; display: flex; flex-direction: column; background-color: #f5f5f5; } /* PDF 查看器容器样式 */ .pdf-viewer { flex: 1; padding: 20px; max-width: 100%; margin: 0 auto; box-sizing: border-box; background-color: white;…...

transformer-词嵌入和位置嵌入详解

文章目录 1、介绍一下位置嵌入Positional Encoding、什么是Positional Encoding呢&#xff1f;为什么Transformer需要Positional Enconding? Transformer 的 Positional Encoding 是如何表达相对位置关系的&#xff1f;2、我来简单举个例子2.1 词向量&#xff1a;每个token都会…...

大模型本地部署之ollama安装及deepseek、qwen等模型下载操作

大模型本地部署之----ollama安装指南 最新版--下载方式 Download Ollama on macOS 因github下载较慢&#xff0c;可以网上搜索github加速工具下载 ----download后加版本号 例如: https://github.com/ollama/ollama/releases/download/v0.6.5/OllamaSetup.exe 通过网盘分享…...

ffprobe 输出 HEVC 码流 Level:标准的 “错位” 与分析的 “归位”

问题描述 最近用ffprobe分析HEVC/H265的码流,发现了与理论知识不符合的现象,比如针对一个H265的码流,用ffprobe输入命令 ffprobe -show_streams 1.h265 时,输入如下;可以看到 H265 的码流 Level 显示等于 93,打印值与标准理论值不符合,用其他工具分析此时 Level 等于 3.…...

线程池七个参数的含义

Java中的线程池里七个参数的以及其各自的含义 面试题&#xff1a;说一下线程池七个参数的含义&#xff1f; 所谓的线程池的 7 大参数是指&#xff0c;在使用 ThreadPoolExecutor 创建线程池时所设置的 7 个参数&#xff0c;如以下源码所示&#xff1a; public ThreadPoolExe…...

EnlightenGAN:低照度图像增强

简介 简介:记录如何使用EnlightenGAN来做低照度图像增强。该论文主要是提供了一个高效无监督的生成对抗网络,通过全球局部歧视器结构,一种自我调节的感知损失融合,以及注意机制来得到无需匹配的图像增强效果。 论文题目:EnlightenGAN: Deep Light Enhancement Without P…...

内存函数和动态内存管理

目录 一、memcpy库函数介绍 1. memcpy的使用 2. memcpy的模拟 二、memmove库函数介绍 1. memmove的使用 2. memmove的模拟 三、memset库函数介绍 四、memcmp库函数介绍 五、动态内存中malloc和free 1. malloc 2. free 六、动态内存中calloc和realloc 1. calloc 2. realloc 七、…...

计算机网络 - 在浏览器中输入 URL 地址到显示主页的过程?

第一步&#xff0c;浏览器通过 DNS 来解析 URL&#xff0c;得到相应的 ip 地址&#xff08;到哪里找) 和 方法&#xff08;做什么&#xff09; 第二步&#xff0c;浏览器于服务器建立 TCP 三次握手连接 第三步&#xff0c;建立好连接后&#xff0c;浏览器会组装 HTTP 请求报文…...

Android Studio 常见报错

错误提示&#xff1a; Your build is currently configured to use incompatible Java 21.0.3 and Gradle 6.7.1. Cannot sync the project. 原因&#xff1a; Java JDK和gradle 版本不匹配 两个角度修改&#xff1a; 1.修改gradle 版本 2.修改JDK版本 Gradle 下载 https:…...