[多线程]多线程编程需要注意的问题|多进程

多线程三个经典问题

https://blog.csdn.net/lisonglisonglisong/article/details/45390227

可重入函数与不可重入函数

 

保证函数的可重入性的方法:

1)在写函数时候尽量使用局部变量(例如寄存器、堆栈中的变量);

2)对于要使用的全局变量要加以保护(如采取关中断、信号量等互斥方法),这样构成的函数就一定是一个可重入的函数。

满足下列条件的函数多数是不可重入(不安全)的:

1)函数体内使用了静态的数据结构;

2)函数体内调用了malloc() 或者 free() 函数;

3)函数体内调用了标准 I/O 函数。

如何将一个不可重入的函数改写成可重入函数呢?

1)不要使用全局变量。因为别的代码很可能改变这些变量值。

2)在和硬件发生交互的时候,切记执行类似 disinterrupt() 之类的操作,就是关闭硬件中断。完成交互记得打开中断,在有些系列上,这叫做“进入/ 退出核心”。

3)不能调用其它任何不可重入的函数。

4)谨慎使用堆栈。

浅谈可重入函数与不可重入函数【转】_shareinfo2018-CSDN博客_可重入函数

fork()的子进程和父进程有什么不同,子进程可以从父进程那里能够继承什么,又不能继承什么

《UNIX系统编程》第24章进程的创建

fork之后父子进程同时从fork点开始执行、

父子进程共享代码抄段,数据段都是完全拷贝,相互之间的更改zhidao不会影响。

(fork之后exec之前两个进程用的是相同的物理空间(内存区),子进程的代码段、数据段、堆栈都是指向父进程的物理空间,也就是说,两者的虚拟空间不同,但其对应的物理空间是同一个。)

但是值得注意的是socket是共享的

互斥锁

std::mutex mu;
// 使用锁保护
void shared_print(string msg, int id) {
    mu.lock(); // 上锁
    cout << msg << id << endl;
    mu.unlock(); // 解锁
}

有一个隐藏着的问题,如果mu.lock()mu.unlock()之间的语句发生了异常,会发生什么?unlock()语句没有机会执行!导致导致mu一直处于锁着的状态,其他使用shared_print()函数的线程就会阻塞。

void shared_print(string msg, int id) {
    //构造的时候帮忙上锁,析构的时候释放锁
    std::lock_guard<std::mutex> guard(mu);
    //mu.lock(); // 上锁
    cout << msg << id << endl;
    //mu.unlock(); // 解锁
}

RAII技术,即获取资源即初始化(Resource Acquisition Is Initialization)技术,这是c++中管理资源的常用方式。 //构造的时候帮忙上锁,(函数退出)析构的时候释放锁

join的必要:
举个例子,现在有 A, B, C 三件事情,只有做完 A 和 B 才能去做 C,而 A 和 B 可以并行完成。

int main(){
    thread t = new thread(A);
    B();  // 此时 A 与 B 并行进行
    t.join();  // 确保 A 完成
    C();
}
 

posted on 2022-10-04 01:26  bdy  阅读(15)  评论(0编辑  收藏  举报

导航