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函数族,守护进程,线程同步和互斥的更多相关文章

  1. 线程同步 - POSIX互斥锁

    线程同步 - POSIX互斥锁 概括 本文讲解POSIX中互斥量的基本用法,从而能达到简单的线程同步.互斥量是一种特殊的变量,它有两种状态:锁定以及解锁.如果互斥量是锁定的,就有一个特定的线程持有或者 ...

  2. 1.2 Linux中的进程 --- fork、vfork、exec函数族、进程退出方式、守护进程等分析

    fork和vfork分析: 在fork还没有实现copy on write之前,Unix设计者很关心fork之后立即执行exec所造成的地址空间浪费,也就是拷贝进程地址空间时的效率问题,所以引入vfo ...

  3. python 守护进程、同步锁、信号量、事件、进程通信Queue

    一.守护进程 1.主进程创建守护进程 其一:守护进程会在主进程代码执行结束后就终止 其二:守护进程内无法再开启子进程,否则抛出异常:AssertionError: daemonic processes ...

  4. Python并发编程-进程 线程 同步锁 线程死锁和递归锁

    进程是最小的资源单位,线程是最小的执行单位 一.进程 进程:就是一个程序在一个数据集上的一次动态执行过程. 进程由三部分组成: 1.程序:我们编写的程序用来描述进程要完成哪些功能以及如何完成 2.数据 ...

  5. UNIX环境高级编程——线程同步之互斥量

    互斥量(也称为互斥锁)出自POSIX线程标准,可以用来同步同一进程中的各个线程.当然如果一个互斥量存放在多个进程共享的某个内存区中,那么还可以通过互斥量来进行进程间的同步. 互斥量,从字面上就可以知道 ...

  6. APUE学习笔记——11 线程同步、互斥锁、自旋锁、条件变量

    线程同步     同属于一个进程的不同线程是共享内存的,因而在执行过程中需要考虑数据的一致性.     假设:进程有一变量i=0,线程A执行i++,线程B执行i++,那么最终i的取值是多少呢?似乎一定 ...

  7. Python3 进程 线程 同步锁 线程死锁和递归锁

    进程是最小的资源单位,线程是最小的执行单位 一.进程 进程:就是一个程序在一个数据集上的一次动态执行过程. 进程由三部分组成: 1.程序:我们编写的程序用来描述进程要完成哪些功能以及如何完成 2.数据 ...

  8. C++线程同步与互斥总结

    互斥:当多个线程访问同一个全局变量,或者同一个资源(比如打印机)的时候,需要进行线程间的互斥操作来保证访问的安全性. 临界区.互斥体.事件和信号量都可以实现线程互斥.但如果仅仅需要实现互斥功能,推荐前 ...

  9. linux线程同步(1)-互斥量

    一.概述                                                   互斥量是线程同步的一种机制,用来保护多线程的共享资源.同一时刻,只允许一个线程对临界区进行 ...

随机推荐

  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 ...

  2. 【Java】一个小程序,计算它包含的代码所需的耗时

    写一个小程序,用来计算它包含的代码所需的耗时.虽然简单,测试代码是否耗时还是有点用的,不用重新写嘛~ import java.util.Date; import java.util.concurren ...

  3. 从零开始学iPhone开发(2)——控件的使用

    这一节我们开始学习iOS中简单控件的使用. 在iOS编程中,简单的控件有很多,其中主要的用的多的有: UILabel,UIButton,UISegmentedControl, UITextField, ...

  4. CSS布局基础之一设备像素,设备独立像素,设备像素比,css像素之间的关系

    设备像素dp(device pixels) ppi(pixels per inch)表示每英寸所拥有的像素(pixel)数目,数值越高,代表屏幕能以更高的密度显示图像. 计算公式:ppi=像素数量/物 ...

  5. Ubuntu安装SSH服务

    1 SSH服务 Ubuntu默认并没有安装ssh服务,如果通过ssh远程连接到Ubuntu,需要自己手动安装ssh-server(openssh-server). 1.1 检测是否安装SSH服务 出现 ...

  6. jQuery实现两个按钮的位置互换

    页面上有2个按钮A和B.点击按钮A和按钮B互换位置 ,点击按钮B和按钮A互换位置.应该如何实现? html代码如下: <body> <!--页面上有2个按钮A和B. 点击按钮A和按钮 ...

  7. hdu 5542 The Battle of Chibi(2015CCPC - C题)

    题目链接:hdu 5542 首届CCPC的C题,比赛时一起搞了好久,最后是队友A出的,当时有试过用树状数组来优化 dp,然后今天下午也用树状数组搞了一下午,结果还是踩了和当时一样的坑:我总是把用来记录 ...

  8. [java基础]分支结构(2)

    [java基础]分支结构2 switch case /** 文件路径:G:\JavaByHands\if-else\ 文件名称:switchcase.java 编写时间:2016/6/6 作 者:郑晨 ...

  9. 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上下载了一个工程后出现以下错误: ...

  10. 20150514Linux下rpm包安装错误及解决方案

    (1)用rpm -ivh ***.rpm解压RedHat自带boost出现错误如下: warning: /media/RHEL_6.3 i386 Disc 1/Packages/boost-1.41. ...