在Linux中,进程可以通过多种方式实现并发执行。以下是一些常见的方法:
多线程是实现并发的一种轻量级方式。一个进程可以包含多个线程,这些线程共享进程的资源(如内存),但每个线程有自己的程序计数器和栈。
pthread_create函数。pthread_join函数。pthread_mutex_t)、条件变量(pthread_cond_t)等来同步线程。#include <pthread.h>
#include <stdio.h>
void* thread_func(void* arg) {
printf("Thread is running\n");
return NULL;
}
int main() {
pthread_t thread;
pthread_create(&thread, NULL, thread_func, NULL);
pthread_join(thread, NULL);
return 0;
}
多进程是通过创建多个独立的进程来实现并发。每个进程有自己的地址空间和资源。
fork函数。exec系列函数(如execl、execp)。pipe)、消息队列(msgget)、共享内存(shmget)等。#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main() {
pid_t pid = fork();
if (pid == 0) {
// 子进程
printf("Child process\n");
execl("/bin/ls", "ls", "-l", NULL);
} else if (pid > 0) {
// 父进程
wait(NULL);
printf("Parent process\n");
} else {
// 错误处理
perror("fork");
}
return 0;
}
异步I/O允许程序在等待I/O操作完成时执行其他任务,从而实现并发。
aio库:Linux提供了异步I/O接口,如aio_read和aio_write。epoll、kqueue等机制来监听多个文件描述符的事件。#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/epoll.h>
#define MAX_EVENTS 10
int main() {
int fd = open("test.txt", O_RDONLY);
if (fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
int epoll_fd = epoll_create1(0);
if (epoll_fd == -1) {
perror("epoll_create1");
close(fd);
exit(EXIT_FAILURE);
}
struct epoll_event event;
event.events = EPOLLIN;
event.data.fd = fd;
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &event) == -1) {
perror("epoll_ctl: fd");
close(fd);
close(epoll_fd);
exit(EXIT_FAILURE);
}
struct epoll_event events[MAX_EVENTS];
while (1) {
int nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
if (nfds == -1) {
perror("epoll_wait");
break;
}
for (int i = 0; i < nfds; i++) {
if (events[i].data.fd == fd) {
char buffer[1024];
ssize_t bytes_read = read(fd, buffer, sizeof(buffer));
if (bytes_read > 0) {
printf("Read %zd bytes: %.*s\n", bytes_read, (int)bytes_read, buffer);
} else if (bytes_read == -1) {
perror("read");
}
}
}
}
close(fd);
close(epoll_fd);
return 0;
}
协程是一种用户态的轻量级线程,可以在单个线程内实现并发。协程的切换由程序员控制,而不是操作系统。
ucontext库:提供上下文切换的接口。libco、Boost.Coroutine等。#include <stdio.h>
#include <ucontext.h>
#define MAX_COROUTINES 10
typedef struct {
ucontext_t context;
int data;
} coroutine_t;
coroutine_t coroutines[MAX_COROUTINES];
int current_coroutine = 0;
void coroutine_func(int id) {
while (1) {
printf("Coroutine %d is running\n", id);
current_coroutine = (current_coroutine + 1) % MAX_COROUTINES;
swapcontext(&coroutines[current_coroutine].context, &coroutines[(current_coroutine - 1 + MAX_COROUTINES) % MAX_COROUTINES].context);
}
}
int main() {
for (int i = 0; i < MAX_COROUTINES; i++) {
getcontext(&coroutines[i].context);
coroutines[i].context.uc_stack.ss_sp = malloc(16384);
coroutines[i].context.uc_stack.ss_size = 16384;
coroutines[i].context.uc_link = NULL;
makecontext(&coroutines[i].context, coroutine_func, 1, i);
}
setcontext(&coroutines[current_coroutine].context);
return 0;
}
通过这些方法,Linux系统可以实现进程的并发执行,从而提高系统的性能和响应能力。