进程通信——system调用外部程序

本文介绍了如何在C/C++程序中通过system调用来非阻塞地运行外部程序,并提供了带参数调用及控制输出数据的方法,如利用echo进行数据追加或覆盖。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

system调用外部程序

用法

  • system(“路径 &”)
    eg: system("./print_list &") 调用当前目录下的print_list
    注意:加&非阻塞运行,不加阻塞运行

  • 带参数调用,输出数据

    char s[255];
	//字符串拼接,将调用的外部程序里的,cout部分输出到txt文件中, path ,symbol为参数
	sprintf(s,"../writeData %s %x %s &", path, symbol, "
### Ubuntu 中的进程间通信方法 #### 管道 (Pipe) 管道是一种半双工的通信方式,适用于具有亲缘关系的进程之间。创建管道可以通过 `pipe` 函数来完成。 ```c #include <unistd.h> int pipe(int pipefd[2]); ``` 此函数会返回两个文件描述符:一个用于读取 (`pipefd[0]`) 和另一个用于写入 (`pipefd[1]`) [^1]。 #### 有名管道 (FIFO) 有名管道也称为命名管道,它不仅可以在有亲缘关系的进程中使用,还可以让无亲缘关系的进程进行通信。有名管道是一个特殊的文件,在文件系统中有对应的路径名。 创建有名管道可以使用 `mkfifo` 或者命令行工具 `mknod`: ```bash mkfifo my_fifo ``` 或者在 C 代码中: ```c #include <sys/stat.h> int mkfifo(const char *pathname, mode_t mode); ``` 当多个进程打开同一个 FIFO 文件时,它们实际上是通过内核中的缓冲区来进行数据交换[^2]。 #### 信号 (Signal) 信号是一种异步的通知机制,用来告知某个特定事件的发生。发送信号给目标进程通常使用 `kill`, `raise`, `alarm` 等函数;而接收并处理这些信号则需设置相应的处理器函数。 ```c #include <signal.h> void (*signal(int signum, void (*handler)(int)))(int); ``` 这使得程序能够响应各种类型的中断或其他外部条件变化。 #### 消息队列 消息队列提供了更高级别的抽象层,允许应用程序向队列发送固定长度的消息对象而不必关心底层细节。有两种类型的消息队列——POSIX 和 System V 风格的消息队列。 对于 POSIX 消息队列来说,操作接口如下所示: ```c mqd_t mq_open(const char *name, int oflag); ssize_t mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msg_prio); ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned int *msg_prio); ``` 而对于 System V 的版本,则涉及到了 IPC 密钥的概念以及一系列不同的 API 调用。 #### 信号量 (Semaphore) 信号量主要用于控制对公共资源或临界资源的访问权限问题。它可以有效地防止竞争状况下的并发错误。Linux 下支持两种主要形式的信号量集:System V 和 POSIX。 初始化 POSIX 信号量的方式为: ```c sem_t sem; if(sem_init(&sem, /*pshared=*/0, /*value=*/1) != 0){ perror("Failed to initialize semaphore"); } ``` 这里第二个参数决定了该信号量是否能在多进程间共享。 #### 共享内存 (Shared Memory) 这是最高效的进程间通讯手段之一,因为它允许多个独立运行的应用直接存取相同的物理内存区域。为了安全起见,一般还会配合其他同步原语一起工作,比如前面提到过的互斥锁或是信号量。 建立一段新的匿名共享内存段可借助于 `shmget()` 来获取 ID 后再调用 `shmat()` 将其附加到当前地址空间里去[^3]。 #### 套接字 (Socket) 套接字提供了一种通用化的网络编程模型,即使在同一台主机上的应用也可以利用 TCP/IP 协议栈来进行高效的数据传输。除了 AF_INET/AF_INET6 地址族外,还有本地域 socket(Unix Domain Socket),专门针对本机内部的服务端口监听与客户端连接请求管理。 创建服务器端监听 socket 描述符的例子如下: ```c struct sockaddr_un addr = { .sun_family = AF_UNIX }; strcpy(addr.sun_path, SOCKET_PATH); int sockfd = socket(AF_UNIX, SOCK_STREAM, 0); bind(sockfd, (struct sockaddr*)&addr, sizeof(struct sockaddr_un)); listen(sockfd, BACKLOG_SIZE); ``` 以上就是在 Ubuntu Linux 平台上常见的几种进程间通信技术及其基本实现概览。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值