尽量避免多进程多线程混用,当下死锁
来源:互联网 发布:淘宝网刷收藏 编辑:程序博客网 时间:2024/06/04 00:22
一句话总结:父进程创建子进程时,子进程会复制父进程的内存(包括锁状态),需仔细处理。
1、死锁例子
#include <stdio.h>
#include <time.h>
#include <pthread.h>
#include <unistd.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void* doit(void* arg)
{
printf("pid = %d begin doit ...\n",static_cast<int>(getpid()));
pthread_mutex_lock(&mutex);
struct timespec ts = {2,0};
nanosleep(&ts, NULL);
pthread_mutex_unlock(&mutex);
printf("pid = %d end doit ...\n",static_cast<int>(getpid()));
returnNULL;
}
int main(void)
{
printf("pid = %d Entering main ...\n",static_cast<int>(getpid()));
pthread_t tid;
pthread_create(&tid, NULL, doit,NULL);
struct timespec ts = {1,0};
nanosleep(&ts, NULL);
if (fork() ==0)
{
doit(NULL);
}
pthread_join(tid, NULL);
printf("pid = %d Exiting main ...\n",static_cast<int>(getpid()));
return0;
}
运行结果:
通过查询进程可以发现死锁了,子进程3071无法往下执行。
原因:父进程创建的线程调用doit()后,对mutex加了锁;此时fork了一个子进程,子进程复制父进程的内存,包括此时的mutex锁状态;父进程接着往后执行直到结束,而子进程调用了doit(),此时mutex处于加锁状态,一直等待,造成死锁。2、解决死锁
如何解决上述问题呢,我们需要在fork子进程前将锁释放掉,fork之后再将父进程的锁加上。用
int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void));pthread_atfork()在fork()之前调用,当调用fork时,内部创建子进程前在父进程中会调用prepare,内部创建子进程成功后,父进程会调用parent ,子进程会调用child。
不过还是尽量少将多进程多线程混在一起。
#include <stdio.h>
#include <time.h>
#include <pthread.h>
#include <unistd.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void* doit(void* arg)
{
printf("pid = %d begin doit ...\n",static_cast<int>(getpid()));
pthread_mutex_lock(&mutex);
struct timespec ts = {2,0};
nanosleep(&ts, NULL);
pthread_mutex_unlock(&mutex);
printf("pid = %d end doit ...\n",static_cast<int>(getpid()));
returnNULL;
}
void prepare(void)
{
printf("pid = %d prepare ...\n",static_cast<int>(getpid()));
pthread_mutex_unlock(&mutex);
}
void parent(void)
{
printf("pid = %d parent ...\n",static_cast<int>(getpid()));
pthread_mutex_lock(&mutex);
}
void child(void)
{
printf("pid = %d child ...\n",static_cast<int>(getpid()));
}
int main(void)
{
pthread_atfork(prepare, parent, child);
printf("pid = %d Entering main ...\n",static_cast<int>(getpid()));
pthread_t tid;
pthread_create(&tid, NULL, doit,NULL);
struct timespec ts = {1,0};
nanosleep(&ts, NULL);
if (fork() ==0)
{
doit(NULL);
}
pthread_join(tid, NULL);
printf("pid = %d Exiting main ...\n",static_cast<int>(getpid()));
return0;
}
- 尽量避免多进程多线程混用,当下死锁
- 避免多线程死锁
- java多线程--避免死锁
- 什么是多线程,锁,死锁,怎么避免死锁
- Linux多线程如何避免死锁
- 多线程操作哈希表避免死锁
- 如何避免多线程中死锁?
- java多线程如何避免死锁
- 小议避免进程退出时的死锁
- 进程同步及避免死锁经典问题
- 银行家算法 避免进程发生死锁
- 多线程之避免死锁(转载)
- Timer处理多线程并发,避免死锁
- Java多线程中如何避免死锁
- 多线程死锁的产生原因及避免
- java 多线程 避免死锁 哲学家就餐问题
- 多线程死锁的产生以及如何避免死锁
- 多线程死锁的产生以及如何避免死锁
- python多线程 简单例子
- BUMPMAPPING WITH GLSL
- java web 在jsp中使用include指令导入带中文的HTML文件乱码问题
- ReactNative分组列表SectionList使用详情及示例详解
- 机器学习
- 尽量避免多进程多线程混用,当下死锁
- Linux系统入门学习:教你在VirtualBox 安装 Ubuntu 15.04
- python学习之路—基础篇
- html总结
- 【python学习笔记】28:scipy的ndimage模块中有关数学形态学
- JavaScript获取当前页Url地址各个部分
- Android6.0 Recovery之后创建读写文件
- 最小二乘法的矩阵解法和梯度下降法的区别在哪里
- hdu 2043 密码