exec函数族,守护进程,线程同步和互斥
2015.3.2
进程和程序有三点不同:
1,存在位置不同,程序:硬盘,磁盘。进程:内存
2. 程序是静态的,进程是动态的
执行./a.out -->bash->bash程序调用fork()-->子进程将./a.out后面的参数存放到argv[].然后调用exec处理这些参数,最后子进程退出,光标闪动
进程进入停止态:1,调试的时候,2,将前台变成后台运行
线程:每个程序加载到内存后可以对应创建一个或多个顺序执行流(能使进程在同一时刻做不止一件事,每个线程处理各自独立的任务)
回调函数
同步和互斥
exec函数族的基本用法参考:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
void printUsage(const char *argv0)
{
fprintf(stderr,
"Usage : %s <exec type>\n"
"exec type : execl\n"
" execlp,\n"
" execv,\n"
" execvp\n",
argv0);
}
int main(int argc, char *argv[])
{
char *vector[] = {"ps","-f",NULL};
if(argc != 2)
{
printUsage(argv[0]);
return 1;
}
if(0 == strcmp(argv[1],"execl"))
{
if(execl("/bin/ps","ps","-f",NULL) < 0)
{
perror("execl error!");
}
}
else if(0 == strcmp(argv[1],"execlp"))
{
if(execlp("ps","ps","-f",NULL) < 0)
{
perror("execlp error!");
}
}
else if(0 == strcmp(argv[1],"execv"))
{
if(execv("/bin/ps",vector) < 0)
{
perror("execv error!");
}
}
else if(0 == strcmp(argv[1],"execvp"))
{
if(execvp("ps",vector) < 0)
{
perror("execvp error!");
}
}
perror("note the program will not step the exec() function met some errors");
return 0;
}
守护进程的创建和出错处理:(守护进程出错,将错误信息输出到文件中,调用日志函数实现)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcnl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main()
{
pid_t pid, sid;
int i,fd;
char *buf = "this is a Daemon\n";
pid = fork();
if(pid < 0)
{
printf("error fork\n");
exit(1);
}
else if(pid > 0)
{
exit(0);
}
openlog("daemon_syslog",LOG_PID,LOD_DAEMON);
if((sid = setsid()) < 0)
{
syslog(LOG_ERR,"%s\n","setsid")
exit(1);
}
if((sid = chdir("/")) < 0)
{
syslog(LOG_ERR,"%s\n","setsid");
exit(1);
}
for(i = 0; i < getdtablesize(); i++)
{
close(i);
}
while(1)
{
if((fd = open("/tmp/daemon.log",O_CREAT|OWRONLY|O_APPEND.0600))<0)
{
syslog(LOG_ERR,"open");
exit(1);
}
write(fd,buf, strlen(buf) + 1);
close(fd);
sleep(10);
}
closelog();
exit(0);
}
线程的创建,结束和回收!
涉及到的相关函数如下:
int pthread_create(pthread_t *thread, pthread_attr_t *attr, void *(start_continue)(void *),void *arg);
void pthread_exit(void *retval);
int pthread_join(pthread_t thread, void **thread_result);
int pthread_cancle(pthread_t thread);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
char message[32] = "hello world";
void *thread_function(void *arg);
int main(int argc, char *argv[])
{
pthread_t a_thread;
void *thread_result;
if(pthread_create(&a_thread, NULL, thread_function,(void *)message) < 0)
{
perror("fail to pthread_create");
exit(-1);
}
printf("waiting for thread to finish\n");
if(pthread_join(a_thread, &thread_result) < 0)
{
perror("fail to prhread_join");
exit(-1);
}
printf("message is now %s\n",message);
return 0;
}
void *thread_function(void *arg)
{
printf("thread_function is runing,argument is %s\n",(char *)arg);
strcpy(message,"marked by thread");
pthread_exit("thank you for the cpu time");
}
上面程序编译的时候用这条语句:gcc XXXX.c -lpthread -D _REENTRANT
-lpthread // 链接pthread库
-D _REENTRANT //生成可重入代码
程序运行结果:
lg@lg-desktop:/mnt/hgfs/source test/file IO$ gcc test13.c -lpthread -D_REENTRANT
lg@lg-desktop:/mnt/hgfs/source test/file IO$ ./a.out
waiting for thread to finish
thread_function is runing,argument is hello world
message is now marked by thread
创建两个线程,分别执行不同的程序,最后退出并由主程序回收。
#include <string.h>
#include <pthread.h>
char message1[] = "AAAAAAAAAA";
char message2[] = "BBBBBBBBBB";
void *thread_function1(void *arg1);
void *thread_function2(void *arg2);
int main(int argc, char *argv[])
{
pthread_t a_thread1,a_thread2;
//void *thread_result;
if(pthread_create(&a_thread1, NULL, thread_function1,(void *)message1) < 0)
{
perror("fail to pthread_create 1");
exit(-1);
}
if(pthread_create(&a_thread2, NULL, thread_function2,(void *)message2) < 0)
{
perror("fail to pthread_create 2");
exit(-1);
}
printf("waiting for thread to finish\n");
if(pthread_join(a_thread1, NULL) < 0)
{
perror("fail to prhread_join");
exit(-1);
}
if(pthread_join(a_thread2,NULL) < 0)
{
perror("fail to prhread_join");
exit(-1);
}
return 0;
}
void *thread_function1(void *arg1)
{
int i;
for(i = 0; i < 3; i++)
{
printf("string is %s \n",(void *)arg1);
sleep(1);
}
pthread_exit("thread 1 is exit");
}
void *thread_function2(void *arg2)
{
int i;
//sleep(10);
for(i = 0; i < 3; i++)
{
printf("string is %s \n",(void *)arg2);
sleep(1);
}
pthread_exit("thread 2 is exit");
}
上面程序的运行结果:
lg@lg-desktop:/mnt/hgfs/source test/file IO$ ./a.out
waiting for thread to finish
string is BBBBBBBBBB
string is AAAAAAAAAA
string is BBBBBBBBBB
string is AAAAAAAAAA
string is BBBBBBBBBB
string is AAAAAAAAAA
lg@lg-desktop:/mnt/hgfs/source test/file IO$
线程间同步:
信号量是一个受保护的量,只能通过三种操作进行访问:
1.初始化
2.P操作(申请资源)
3.V操作(释放资源)
信号量的值是非负整数
p操作包含下面内容:
if(信号量 > 0)
{
申请资源的任务继续运行;
信号量的值 - 1;
}
else
{
申请资源的任务阻塞;
}
v操作包含下面的内容:
if(没有任务在等待资源)
{
信号量的值 + 1;
}
else
{
唤醒第一个等待的任务,让其继续运行;
}
同步中涉及到的常用的信号量操作函数如下:
int sem_init(sem_t *sem, int pshared, unsigned int value);
int sem_wait(sem_t *sem);
int sem_post(sem_t *sem);
int sem_trywait(sem_t *sem);
int sem_getvalue(sem_t *sem, int svalue);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
char buf[60];
sem_t sem;
void *function(void * arg);
int main(int argc,char **argv)
{
pthread_t a_thread;
void *thread_result;
if(sem_init(&sem,0,0) < 0)
{
perror("fail to sem_init");
exit(-1);
}
if(pthread_create(&a_thread,NULL,function,NULL) < 0)
{
perror("fail to pthread_create");
exit(-1);
}
printf("input 'quit' to exit\n");
do
{
fgets(buf, 60, stdin);
sem_post(&sem);
}while(strncmp(buf,"quit",4) != 0);
return 0;
}
void *function(void * arg)
{
while(1)
{
sem_wait(&sem);
printf("you enter %d characters\n",strlen(buf)-1);
}
}
进程间互斥:加互斥锁
互斥锁涉及到的一些常用函数如下:
int pthread_mutex_init(pthread_mutex_t *mutex, pthread_mutexattr_t *attr);
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
//#define _LOCK_
unsigned int value1, value2,count;
pthread_mutex_t mutex;
void *function(void *arg);
int main(int argc,char ** argv)
{
pthread_t a_thread;
if(pthread_mutex_init(&mutex,NULL) < 0)
{
perror("fail to mutex_init");
exit(-1);
}
if(pthread_create(&a_thread, NULL, function,NULL) < 0)
{
perror("fail to pthread_create");
exit(-1);
}
while(1)
{
count++;
#ifdef _LOCK_
pthread_mutex_lock(&mutex);
#endif
value1 = count;
value2 = count;
#ifdef _LOCK_
pthread_mutex_unlock(&mutex);
#endif
}
return 0;
}
void *function(void *arg)
{
while(1)
{
#ifdef _LOCK_
pthread_mutex_lock(&mutex);
#endif
if(value1 != value2)
{
printf("count = %d, value1 = %d, value2 = %d\n",count, value1, value2);
usleep(100000);
}
#ifdef _LOCK_
pthread_mutex_unlock(&mutex);
#endif
}
return NULL;
}
将define _LOCK_ 屏蔽后运行结果:(不屏蔽程序没有输出,value1和value2相等)
lg@lg-desktop:/mnt/hgfs/source test/file IO$ gcc lock14.c -lpthread -D_REENTRANT
lg@lg-desktop:/mnt/hgfs/source test/file IO$ ./a.out
count = 3338702, value1 = 3338702, value2 = 3338701
count = 53692966, value1 = 53692966, value2 = 53692965
count = 89910265, value1 = 89910265, value2 = 89910264
count = 125008213, value1 = 125008213, value2 = 125008212
count = 149351134, value1 = 149351134, value2 = 149351133
count = 171729575, value1 = 171729575, value2 = 171729574
count = 228510044, value1 = 228510044, value2 = 228510043
count = 256495259, value1 = 256495259, value2 = 256495258
count = 287733530, value1 = 287733530, value2 = 287733529
count = 324321776, value1 = 324321776, value2 = 324321775
count = 365523395, value1 = 365523395, value2 = 365523394
count = 420680808, value1 = 420680808, value2 = 420680807
count = 448359597, value1 = 448359597, value2 = 448359596
count = 494800004, value1 = 494800004, value2 = 494800003
count = 528839826, value1 = 528839826, value2 = 528839825
^C
lg@lg-desktop:/mnt/hgfs/source test/file IO$ ^C
lg@lg-desktop:/mnt/hgfs/source test/file IO$
互斥锁的另一个参考程序;
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define THREAD_NUM 3
#define REPEAT_NUM 3
#define DELAY_TIME_LEVELS 3.0
pthread_mutex_t mutex;
void *thrd_func(void *arg)
{
int thrd_num = (int)arg;
int delay_time = 0;
int count = 0;
int res;
res = pthread_mutex_lock(&mutex);
if(res)
{
printf("thread %d lock failed\n",thrd_num);
pthread_exit(NULL);
}
printf("thread %d is starting\n",thrd_num);
for(count = 0; count < REPEAT_NUM; count++)
{
delay_time = (int)(rand() * DELAY_TIME_LEVELS/(RAND_MAX)) + 1;
sleep(delay_time);
printf("\tThread %d:job %d delay = %d\n",
thrd_num,count, delay_time);
}
printf("thread %d finished\n",thrd_num);
pthread_mutex_unlock(&mutex);
pthread_exit(NULL);
}
int main(void)
{
pthread_t thread[THREAD_NUM];
int no = 0, tpid;
void *thrd_ret;
srand(time(NULL));
pthread_mutex_init(&mutex,NULL);
for(no = 0; no < THREAD_NUM; no++)
{
tpid = pthread_create(&thread[no],NULL,thrd_func,(void *)no);
if(tpid != 0)
{
printf("create thread %d failed\n",no);
exit(-1);
}
}
printf("create treates success\nwaiting for threads to finish...\n");
for(no = 0; no < THREAD_NUM; no++)
{
tpid = pthread_join(thread[no],&thrd_ret);
if(tpid == 0)
{
printf("thread %d joined\n",no);
}
else
{
printf("thread %d join failed\n",no);
}
}
pthread_mutex_destroy(&mutex);
return 0;
}
上面程序运行结果:(结果和书本上有所不同,分析原因是线程执行顺序不同,但是第一个thread 2 is starting有疑问,应该是thread 0 is starting才对,有待解决)
lg@lg-desktop:/mnt/hgfs/source test/file IO$ gcc thread_mutex.c -lpthread -D_REENTRANT
thread_mutex.c: In function ‘thrd_func’:
thread_mutex.c:14: warning: cast from pointer to integer of different size
thread_mutex.c: In function ‘main’:
thread_mutex.c:58: warning: cast to pointer from integer of different size
lg@lg-desktop:/mnt/hgfs/source test/file IO$ ./a.out
create treates success
waiting for threads to finish...
thread 2 is starting
Thread 2:job 0 delay = 3
Thread 2:job 1 delay = 3
Thread 2:job 2 delay = 1
thread 2 finished
thread 1 is starting
Thread 1:job 0 delay = 1
Thread 1:job 1 delay = 1
Thread 1:job 2 delay = 1
thread 1 finished
thread 0 is starting
Thread 0:job 0 delay = 3
Thread 0:job 1 delay = 3
Thread 0:job 2 delay = 2
thread 0 finished
thread 0 joined
thread 1 joined
thread 2 joined
lg@lg-desktop:/mnt/hgfs/source test/file IO$
***************************************************************************************************************************************************************
***************************************************************************************************************************************************************
***************************************************************************************************************************************************************
***************************************************************************************************************************************************************
exec函数族,守护进程,线程同步和互斥的更多相关文章
- 线程同步 - POSIX互斥锁
线程同步 - POSIX互斥锁 概括 本文讲解POSIX中互斥量的基本用法,从而能达到简单的线程同步.互斥量是一种特殊的变量,它有两种状态:锁定以及解锁.如果互斥量是锁定的,就有一个特定的线程持有或者 ...
- 1.2 Linux中的进程 --- fork、vfork、exec函数族、进程退出方式、守护进程等分析
fork和vfork分析: 在fork还没有实现copy on write之前,Unix设计者很关心fork之后立即执行exec所造成的地址空间浪费,也就是拷贝进程地址空间时的效率问题,所以引入vfo ...
- python 守护进程、同步锁、信号量、事件、进程通信Queue
一.守护进程 1.主进程创建守护进程 其一:守护进程会在主进程代码执行结束后就终止 其二:守护进程内无法再开启子进程,否则抛出异常:AssertionError: daemonic processes ...
- Python并发编程-进程 线程 同步锁 线程死锁和递归锁
进程是最小的资源单位,线程是最小的执行单位 一.进程 进程:就是一个程序在一个数据集上的一次动态执行过程. 进程由三部分组成: 1.程序:我们编写的程序用来描述进程要完成哪些功能以及如何完成 2.数据 ...
- UNIX环境高级编程——线程同步之互斥量
互斥量(也称为互斥锁)出自POSIX线程标准,可以用来同步同一进程中的各个线程.当然如果一个互斥量存放在多个进程共享的某个内存区中,那么还可以通过互斥量来进行进程间的同步. 互斥量,从字面上就可以知道 ...
- APUE学习笔记——11 线程同步、互斥锁、自旋锁、条件变量
线程同步 同属于一个进程的不同线程是共享内存的,因而在执行过程中需要考虑数据的一致性. 假设:进程有一变量i=0,线程A执行i++,线程B执行i++,那么最终i的取值是多少呢?似乎一定 ...
- Python3 进程 线程 同步锁 线程死锁和递归锁
进程是最小的资源单位,线程是最小的执行单位 一.进程 进程:就是一个程序在一个数据集上的一次动态执行过程. 进程由三部分组成: 1.程序:我们编写的程序用来描述进程要完成哪些功能以及如何完成 2.数据 ...
- C++线程同步与互斥总结
互斥:当多个线程访问同一个全局变量,或者同一个资源(比如打印机)的时候,需要进行线程间的互斥操作来保证访问的安全性. 临界区.互斥体.事件和信号量都可以实现线程互斥.但如果仅仅需要实现互斥功能,推荐前 ...
- linux线程同步(1)-互斥量
一.概述 互斥量是线程同步的一种机制,用来保护多线程的共享资源.同一时刻,只允许一个线程对临界区进行 ...
随机推荐
- 2016年12月24日 星期六 --出埃及记 Exodus 21:19
2016年12月24日 星期六 --出埃及记 Exodus 21:19 the one who struck the blow will not be held responsible if the ...
- 【Java】一个小程序,计算它包含的代码所需的耗时
写一个小程序,用来计算它包含的代码所需的耗时.虽然简单,测试代码是否耗时还是有点用的,不用重新写嘛~ import java.util.Date; import java.util.concurren ...
- 从零开始学iPhone开发(2)——控件的使用
这一节我们开始学习iOS中简单控件的使用. 在iOS编程中,简单的控件有很多,其中主要的用的多的有: UILabel,UIButton,UISegmentedControl, UITextField, ...
- CSS布局基础之一设备像素,设备独立像素,设备像素比,css像素之间的关系
设备像素dp(device pixels) ppi(pixels per inch)表示每英寸所拥有的像素(pixel)数目,数值越高,代表屏幕能以更高的密度显示图像. 计算公式:ppi=像素数量/物 ...
- Ubuntu安装SSH服务
1 SSH服务 Ubuntu默认并没有安装ssh服务,如果通过ssh远程连接到Ubuntu,需要自己手动安装ssh-server(openssh-server). 1.1 检测是否安装SSH服务 出现 ...
- jQuery实现两个按钮的位置互换
页面上有2个按钮A和B.点击按钮A和按钮B互换位置 ,点击按钮B和按钮A互换位置.应该如何实现? html代码如下: <body> <!--页面上有2个按钮A和B. 点击按钮A和按钮 ...
- hdu 5542 The Battle of Chibi(2015CCPC - C题)
题目链接:hdu 5542 首届CCPC的C题,比赛时一起搞了好久,最后是队友A出的,当时有试过用树状数组来优化 dp,然后今天下午也用树状数组搞了一下午,结果还是踩了和当时一样的坑:我总是把用来记录 ...
- [java基础]分支结构(2)
[java基础]分支结构2 switch case /** 文件路径:G:\JavaByHands\if-else\ 文件名称:switchcase.java 编写时间:2016/6/6 作 者:郑晨 ...
- java.lang.UnsupportedClassVersionError: org/apache/maven/cli/MavenCli : Unsupported major.minor version 51
http://blog.csdn.net/e_wsq/article/details/52100234 一日换了一下MyEclipse,换成2016CI,结果从SVN上下载了一个工程后出现以下错误: ...
- 20150514Linux下rpm包安装错误及解决方案
(1)用rpm -ivh ***.rpm解压RedHat自带boost出现错误如下: warning: /media/RHEL_6.3 i386 Disc 1/Packages/boost-1.41. ...