📅  最后修改于: 2023-12-03 15:27:16.897000             🧑  作者: Mango
在UNIX/Linux系统中,系统调用是应用程序与操作系统之间的接口,允许应用程序请求操作系统提供的服务和资源。System V是UNIX操作系统中的一个版本,其中包含了许多常用的系统调用。以下是一些常见的System V系统调用和用法:
fork()
fork()
系统调用用于创建一个新进程,该进程称为子进程,它是调用进程(即父进程)的副本。子进程从调用fork()
之后的代码行开始执行,而父进程则继续执行其原来的代码。
#include <unistd.h>
#include <stdio.h>
int main() {
pid_t pid = fork();
if (pid == 0) {
printf("Child process\n");
} else {
printf("Parent process, child PID=%d\n", pid);
}
return 0;
}
wait()
wait()
系统调用用于使进程等待其子进程结束,并获取子进程的退出状态。
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
pid_t pid = fork();
if (pid == 0) {
printf("Child process\n");
exit(42);
} else {
int status;
wait(&status);
if (WIFEXITED(status)) {
printf("Child exited with status %d\n", WEXITSTATUS(status));
}
}
return 0;
}
exec()
exec()
系列系统调用用于将当前进程替换为新进程映像。execve()
是其中最通用的一个,它允许指定新进程的路径、命令行参数和环境变量。
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
char *argv[] = { "/bin/ls", "-l", NULL };
char *envp[] = { NULL };
execve(argv[0], argv, envp);
perror("execve");
return 1;
}
open()
open()
系统调用用于打开一个文件,并返回文件描述符(文件句柄)。如果文件不存在,则可以使用相应的标志创建新文件。
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
int fd = open("file.txt", O_CREAT | O_WRONLY, 0666);
if (fd == -1) {
perror("open");
return 1;
}
write(fd, "Hello, world!\n", 14);
close(fd);
return 0;
}
read()
read()
系统调用用于从文件描述符读取数据,并将其存储在缓冲区中。返回值是读取的字节数,如果到达文件末尾则返回0,出错则返回-1。
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define BUF_SIZE 1024
int main() {
int fd = open("file.txt", O_RDONLY);
if (fd == -1) {
perror("open");
return 1;
}
char buf[BUF_SIZE];
int n;
while ((n = read(fd, buf, BUF_SIZE)) != 0) {
if (n == -1) {
perror("read");
close(fd);
return 1;
}
write(STDOUT_FILENO, buf, n);
}
close(fd);
return 0;
}
write()
write()
系统调用用于将数据从缓冲区写入文件描述符。它返回成功写入的字节数,如果出错则返回-1。
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define BUF_SIZE 1024
int main() {
int fd = open("file.txt", O_WRONLY | O_APPEND);
if (fd == -1) {
perror("open");
return 1;
}
char buf[BUF_SIZE] = "Hello again, world!\n";
int n = write(fd, buf, strlen(buf));
if (n == -1) {
perror("write");
close(fd);
return 1;
}
close(fd);
return 0;
}
pipe()
pipe()
系统调用创建一个半双工管道(即只能单向传递数据的管道),并返回两个文件描述符作为结果。它通常由父进程在fork()
之后的代码中使用,用于与子进程通信。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
int fd[2];
if (pipe(fd) == -1) {
perror("pipe");
return 1;
}
pid_t pid = fork();
if (pid == -1) {
perror("fork");
return 1;
} else if (pid == 0) {
close(fd[1]);
char buf;
while (read(fd[0], &buf, 1) > 0) {
write(STDOUT_FILENO, &buf, 1);
}
close(fd[0]);
_exit(EXIT_SUCCESS);
} else {
close(fd[0]);
char *message = "Hello, world!\n";
write(fd[1], message, strlen(message));
close(fd[1]);
wait(NULL);
}
return 0;
}
msgget()
msgget()
系统调用创建或打开一个消息队列,并返回其标识符。标识符由系统内部维护,可以用于后续的系统调用。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
struct my_message {
long mtype;
char mtext[80];
};
int main() {
key_t key = ftok(".", 'a');
if (key == -1) {
perror("ftok");
return 1;
}
int msqid = msgget(key, IPC_CREAT | 0666);
if (msqid == -1) {
perror("msgget");
return 1;
}
struct my_message message;
message.mtype = 1;
strncpy(message.mtext, "Hello, world!", 80);
if (msgsnd(msqid, &message, strlen(message.mtext) + 1, 0) == -1) {
perror("msgsnd");
return 1;
}
sleep(1);
if (msgrcv(msqid, &message, 80, 0, 0) == -1) {
perror("msgrcv");
return 1;
}
printf("Received message: %s\n", message.mtext);
if (msgctl(msqid, IPC_RMID, NULL) == -1) {
perror("msgctl");
return 1;
}
return 0;
}
shmget()
shmget()
系统调用创建或打开一个共享内存段,并返回其标识符。标识符由系统内部维护,可以用于后续的系统调用。
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
int shmid = shmget(IPC_PRIVATE, 8, IPC_CREAT | 0666);
if (shmid == -1) {
perror("shmget");
return 1;
}
char *data = shmat(shmid, NULL, 0);
if (data == (char *) -1) {
perror("shmat");
return 1;
}
strncpy(data, "hello", 8);
if (shmdt(data) == -1) {
perror("shmdt");
return 1;
}
return 0;
}
pthread_create()
pthread_create()
系统调用创建一个新的线程,并将其执行起点设置为指定的函数。线程的参数可以通过一个指针传递。
#include <pthread.h>
#include <stdio.h>
void *thread_func(void *arg) {
int n = *(int *)arg;
printf("Thread running. Argument: %d\n", n);
return NULL;
}
int main() {
pthread_t thread;
int arg = 42;
if (pthread_create(&thread, NULL, thread_func, &arg) != 0) {
perror("pthread_create");
return 1;
}
pthread_join(thread, NULL);
return 0;
}
pthread_mutex_lock()
pthread_mutex_lock()
和pthread_mutex_unlock()
系统调用用于控制对共享资源的访问,以避免竞态条件(race condition)。在使用共享资源之前,线程可以调用pthread_mutex_lock()
,以获得互斥锁;在使用完后,必须调用pthread_mutex_unlock()
,以释放该锁。
#include <pthread.h>
#include <stdio.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int shared_resource = 0;
void *thread_func(void *arg) {
pthread_mutex_lock(&mutex);
shared_resource++;
printf("Thread running. Resource value: %d\n", shared_resource);
pthread_mutex_unlock(&mutex);
return NULL;
}
#define NUM_THREADS 10
int main() {
pthread_t threads[NUM_THREADS];
for (int i = 0; i < NUM_THREADS; i++) {
if (pthread_create(&threads[i], NULL, thread_func, NULL) != 0) {
perror("pthread_create");
return 1;
}
}
for (int i = 0; i < NUM_THREADS; i++) {
pthread_join(threads[i], NULL);
}
return 0;
}
以上是一些常见的System V系统调用和用法,它们是UNIX/Linux编程的基础,值得程序员深入学习。