1. 文件操作
1.1 open打开文件
导入库文件
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
int fd = open(pathname,flags)
pathname
:文件路径。flags
:打开方式,可以是以下选项的组合:O_RDONLY
:只读打开。O_WRONLY
:只写打开。O_RDWR
:读写打开。O_CREAT
:如果文件不存在,则创建文件。O_TRUNC
:打开文件时将文件长度截为 0。O_APPEND
:追加模式。
mode
:当使用O_CREAT
创建文件时,需要指定权限。
返回值:成功时返回文件描述符,失败时返回 -1 并设置 errno
。
1.2close关闭文件
close(fd)关闭一个打开的文件描述符
- open():打开和可能创建一个文件,返回一个文件描述符。
- lseek():
1.3 read读取文件
read (fd):从文件描述符指向的文件中读取数据.
1.4 write写入文件
write(fd):向文件描述符指向的文件中写入数据.
1.5返回文件指针位置
lseek(fd)移动文件读写位置指针。
- 第一个参数:
fd
是文件描述符,用于指定需要操作的文件。 - 第二个参数:
offset
是偏移量,用于指定移动的位置,可以是正值、负值或零。 - 第三个参数:
whence
指定偏移的起始位置,常用值有:SEEK_SET
:文件的开头,偏移量从文件开始处计算。SEEK_CUR
:文件的当前位置,偏移量基于当前的位置。SEEK_END
:文件的末尾,偏移量基于文件末尾处计算。-
// 将文件指针移动到文件开头偏移 100 字节的位置 lseek(fd, 100, SEEK_SET); // 将文件指针向后移动 50 字节(从当前位置开始) lseek(fd, 50, SEEK_CUR); // 将文件指针移动到文件末尾前 20 字节的位置 lseek(fd, -20, SEEK_END);
1.6改变文件权限
chmod
2. 进程管理
程序是指令和数据的集合,以文件的形式的存储在磁盘上
进程:是程序一次执行过程以及该过程获得的内存和时间片
- 系统自己分配资源,有自己的代码段,数据段,堆栈段,
- 每个程序至少有一个进程,也可以有多个进程
- 是进行的资源分配和调度的单元
pid() 进程id ppid()父进程id
进程的创建
fork()创建子进程 返回0 则创建成功
system()
exec()
进程的状态
新建 :进程正在创建中
就绪 :进程准备好,等待分配cpu时间
运行:进程正在执行
等待/阻塞:等待某些进程的完成
结束:进程结束
进程间通信(IPC)
- 当多个进程协作时,它们需要交换信息。常见的通信方式包括:
- 信号(Signals): 用于进程间发送通知。
- 管道(Pipes): 单向通信的机制。
- 消息队列(Message Queues): 用于发送和接收消息。
- 共享内存(Shared Memory): 多个进程共享同一段内存,实现高效通信。
- 套接字(Sockets): 用于网络通信的进程间通信方式。
3. 线程管理
线程:多个线程共享进程的所有资源,
最小的执行单位,
一个进程至少有一个主线程
线程的创建:
pthread_t *a;
pthread_create(
tidp, 线程标识符指针
attr, 线程属性指针
start_rtn,线程运行函数的起始地址
arg 传递给线程运行函数的参数)
pthread_self() 获取线程号
信号量初始化:
1) 信号量
2) 0表示单进程多线程中使用,非0表示在多进程中使用
3) 初始值
sem_wait()
sem_post()
sem_destory()
- 互斥锁 mutex
pthread_mutex_t mut;
//上锁
pthread_mutex_lock(&mut);
//解锁
pthread_mutex_unlock(mut);
- 条件变量
生产者消费者模型
// 生产者--消费者模型
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
// 预处理器,定义宏
#define MAX 5
// 全局变量
int queue = 0;
// 互斥锁
//pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
// 条件变量,阻塞与唤醒
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
// 进程中的独立执行单元
void *producer(void *);
void *consumer(void *);
// sem_t sem_p;
// sem_t sem_c;
int main(int argc, char const *argv[])
{
pthread_t t1, t2;
int n = 50;
// p = 50
// sem_init(&sem_p,0,50);
// // c = 0
// sem_init(&sem_c,0,0);
// sem_post(&sem_p);
// sem_wait(&sem_c);
pthread_create(&t1, NULL, producer, &n);
pthread_create(&t2, NULL, consumer, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
printf("over\n");
return 0;
}
void *producer(void *arg)
{
// 获得参数,生产数量
int n = *((int *)arg);
// 生产过程
// 上锁
pthread_mutex_lock(&mut);
for (size_t i = 1; i <= n; i++)
{
if (queue >= 5)
{
printf("队列满了,生产者进入阻塞状态\n");
// 阻塞
pthread_cond_wait(&cond, &mut);
// pthread_cond_timedwait(&cond,&mut,t); 等到t时间解锁或被唤醒
}
queue++;
printf("生产了:%d, 序号:%ld\n", queue, i);
// 唤醒
pthread_cond_signal(&cond);
// pthread_cond_broadcast(&cond);
}
// 解锁
pthread_mutex_unlock(&mut);
pthread_exit(NULL);
}
void *consumer(void *arg)
{
pthread_mutex_lock(&mut);
while (1)
{
if (queue < 1)
{
printf("队列空,消费者进入阻塞状态\n");
pthread_cond_wait(&cond, &mut);
}
pthread_cond_signal(&cond);
printf("消费了 :%d\n",queue);
// printf("消费了:%d\n", queue--);
queue--;
}
pthread_mutex_unlock(&mut);
pthread_exit(NULL);
}
4. 网络编程
参考之前的文章http://t.csdnimg.cn/Vaqml
5.多任务和并发控制
在Linux系统编程中,多任务和并发控制是两个关键主题。多任务指操作系统能够同时处理多个任务,而并发控制则关注在多任务环境中如何管理多个任务之间的相互配合和资源竞争。
多任务与并发控制的概念
-
多任务(Multitasking)
- 多任务是指操作系统能够同时运行多个任务,这些任务可以是多个进程或多个线程。Linux支持抢占式多任务,即操作系统可以在任何时刻中断一个正在运行的任务并切换到另一个任务。
- 多进程: 每个进程有独立的地址空间,进程间相互独立。
- 多线程: 多个线程共享进程的地址空间,但有各自的执行路径和栈空间。
-
并发(Concurrency)与并行(Parallelism)
- 并发: 在同一时间段内处理多个任务,但不一定同时执行。通过任务切换实现并发。
- 并行: 在同一时刻真正地同时执行多个任务,通常依赖于多核处理器。
进程与线程的创建和控制
-
进程控制
- 在Linux中,进程创建通常使用
fork()
系统调用。fork()
创建一个子进程,它是父进程的拷贝。 - 进程的终止: 使用
exit()
或kill()
终止进程。父进程可以使用wait()
或waitpid()
等函数等待子进程结束并获取其状态。
- 在Linux中,进程创建通常使用
-
线程控制
- Linux下的线程是轻量级进程(LWP),通常使用
pthread
库创建线程。pthread_create()
是创建新线程的主要函数。 - 线程同步: 多线程编程中,多个线程访问共享资源时需要同步控制。常用的同步机制有互斥锁(mutex)、条件变量(condition variables)和信号量(semaphores)。
- Linux下的线程是轻量级进程(LWP),通常使用
并发控制与同步机制
并发控制主要通过以下机制实现:
-
互斥锁(Mutex)
- 互斥锁确保在任意时刻只有一个线程可以访问共享资源。一个线程获取互斥锁后,其他线程必须等待该锁被释放。
- 常用函数包括
pthread_mutex_lock()
和pthread_mutex_unlock()
。
-
读写锁(Read-Write Lock)
- 读写锁允许多个线程同时读共享资源,但在写时要求独占访问。
- 常用函数有
pthread_rwlock_rdlock()
和pthread_rwlock_wrlock()
。
-
信号量(Semaphore)
- 信号量是一种更灵活的同步机制,可以控制多个线程对共享资源的访问。
sem_wait()
和sem_post()
是常用的操作函数。
-
条件变量(Condition Variables)
- 条件变量用于在线程之间进行复杂的同步,通常与互斥锁一起使用。线程可以等待某个条件变为真,然后继续执行。
- 常用函数有
pthread_cond_wait()
和pthread_cond_signal()
。
-
自旋锁(Spinlock)
- 自旋锁是轻量级的锁机制,线程在等待锁时不会进入休眠,而是持续检查锁的状态。自旋锁适用于锁定时间短的场景。
进程间通信(IPC)
多任务系统中,进程间通信(IPC)是进程协作的基础。常见的IPC机制有:
-
管道(Pipes)
- 管道是单向通信的机制,通常用于父子进程之间的数据传递。包括匿名管道和命名管道(FIFO)。
-
消息队列(Message Queues)
- 消息队列是消息的链表,允许进程以有序的方式发送和接收消息。
-
共享内存(Shared Memory)
- 共享内存是最快的IPC方式,允许多个进程直接读写同一块内存区域。
-
信号(Signals)
- 信号是异步通知机制,用于通知进程某些事件的发生,如
SIGINT
、SIGKILL
等。
- 信号是异步通知机制,用于通知进程某些事件的发生,如
-
套接字(Sockets)
- 套接字用于不同主机之间的进程通信,是网络编程的基础。
以下是一个使用POSIX线程进行并发控制的示例:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
pthread_mutex_t lock;
int shared_counter = 0;
void* increment(void* arg) {
for (int i = 0; i < 100000; i++) {
pthread_mutex_lock(&lock);
shared_counter++;
pthread_mutex_unlock(&lock);
}
return NULL;
}
int main() {
pthread_t threads[2];
pthread_mutex_init(&lock, NULL);
for (int i = 0; i < 2; i++) {
pthread_create(&threads[i], NULL, increment, NULL);
}
for (int i = 0; i < 2; i++) {
pthread_join(threads[i], NULL);
}
printf("Final counter value: %d\n", shared_counter);
pthread_mutex_destroy(&lock);
return 0;
}
在这个例子中,两个线程并发地增加一个共享计数器,使用互斥锁确保每次只有一个线程修改计数器的值。