一、读写锁:
一种交易场所:变量、数组、链表等其他数据结构
两种角色:读者、写者
三种关系:读者和写者之间没有关系;写者与写者之间互斥;读者与写者之间同步和互斥关系
读者与读者之间共享,读者与写者之间必须等一方解锁,另一方才能加锁;读者与写者线程同时竞争锁,写者会优先获取到锁
1.案例:
代码:
# include<stdio.h>
# include<stdlib.h>
# include<unistd.h>
# include<pthread.h>
1.实现一个交易场所:
int count;
2、创建两个角色
pthread_rwlock_t g_lock;
3、实现三种关系,使用读写锁
void *Read(void *arg){
(void)arg;
while (1){
pthread_rwlock_rdlock(&g_lock);
printf("count=%d\n", count);
usleep(12345);
}
return NULL;
}
void *Write(void *arg)
{
(void)arg;
while (1){
pthread_rwlock_wrlock(&g_lock);
++count;
pthread_rwlock_unlock(&g_lock);
usleep(123456);
}
return NULL;
}
int main()
{
pthread_rwlock_init(&g_lock, NULL);
pthread_t tid1, tid2;
pthread_create(&tid1, NULL, Read, NULL);
pthread_create(&tid2, NULL, Write, NULL);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
pthread_rwlock_destroy(&g_lock);
}
结果:
一种交易场所:变量、数组、链表等其他数据结构
两种角色:读者、写者
三种关系:读者和写者之间没有关系;写者与写者之间互斥;读者与写者之间同步和互斥关系
读者与读者之间共享,读者与写者之间必须等一方解锁,另一方才能加锁;读者与写者线程同时竞争锁,写者会优先获取到锁
1.案例:
代码:
# include<stdio.h>
# include<stdlib.h>
# include<unistd.h>
# include<pthread.h>
1.实现一个交易场所:
int count;
2、创建两个角色
pthread_rwlock_t g_lock;
3、实现三种关系,使用读写锁
void *Read(void *arg){
(void)arg;
while (1){
pthread_rwlock_rdlock(&g_lock);
printf("count=%d\n", count);
usleep(12345);
}
return NULL;
}
void *Write(void *arg)
{
(void)arg;
while (1){
pthread_rwlock_wrlock(&g_lock);
++count;
pthread_rwlock_unlock(&g_lock);
usleep(123456);
}
return NULL;
}
int main()
{
pthread_rwlock_init(&g_lock, NULL);
pthread_t tid1, tid2;
pthread_create(&tid1, NULL, Read, NULL);
pthread_create(&tid2, NULL, Write, NULL);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
pthread_rwlock_destroy(&g_lock);
}
结果:
二、进程间关系和进程守护
守护进程:
代码:
# include<stdio.h>
# include<stdlib.h>
# include<unistd.h>
# include<signal.h>
# include<fcntl.h>
守护进程:
代码:
# include<stdio.h>
# include<stdlib.h>
# include<unistd.h>
# include<signal.h>
# include<fcntl.h>
void mydaemon(void)
{
1.创建子进程,让父进程结束,子进程继续执行
pid_t pid;
if (pid>0){
exit(0);
}
2.子进程调用setsid,创建一个新的会话
setsid();
3.忽略SIGHUP,SIGCHLD
signal(SIGHUP, SIG_IGN);
signal(SIGCHLD, SIG_IGN);
4.修改工作目录为根目录
chdir("/");
5.对标准输出和标准错误进行重定向
int fd = open("/dev/null", O_RDWR);
dup2(fd, 1);
dup2(fd, 2);
6.修改umask
umask(0);
}
int main()
{
mydaemon();
while (1){
sleep(1);
}
return 0;
}
{
1.创建子进程,让父进程结束,子进程继续执行
pid_t pid;
if (pid>0){
exit(0);
}
2.子进程调用setsid,创建一个新的会话
setsid();
3.忽略SIGHUP,SIGCHLD
signal(SIGHUP, SIG_IGN);
signal(SIGCHLD, SIG_IGN);
4.修改工作目录为根目录
chdir("/");
5.对标准输出和标准错误进行重定向
int fd = open("/dev/null", O_RDWR);
dup2(fd, 1);
dup2(fd, 2);
6.修改umask
umask(0);
}
int main()
{
mydaemon();
while (1){
sleep(1);
}
return 0;
}
结果:
法二:
代码:
int main()
{
daemon(0,0);
while (1){
sleep(1);
}
return 0;
}
{
daemon(0,0);
while (1){
sleep(1);
}
return 0;
}
使用nohup把进程变为守护进程(不会立即创建会话ID,不会岁会话ID的终止而终止)
nohup ./文件名 &
ps axj | grep 文件名
daemon(0,0):第一个0:修改工作目录为根目录;第二个0:对标准输出,标准错误进行重定向
关闭窗口
关闭窗口
结果:
ps axj | grep 文件名
ps axj | grep 文件名