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. jquery简单动画

    自定义滑入滑出动画 <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Defaul ...

  2. linux下解压war格式的包

    linux解压 .war 包 war格式的包可以解决web应用程序部署时候不用按照目录层次结构部署,而是将war包当作部署单元来使用. 下面就讲下怎么去解压 .war 格式的压缩包: 1.安装jdk, ...

  3. CentOs 设置静态IP 方法

    在做项目时由于局域网采用自动获取IP的方式,导到每次服务器重启主机IP都会变化. 为了解决这个问题,需要设置静态IP. 1.修改网卡配置 编辑:vi /etc/sysconfig/network-sc ...

  4. TextInfo

    https://msdn.microsoft.com/en-us/library/system.globalization.textinfo.totitlecase(v=vs.110).aspx Co ...

  5. Writing Text Files On The Client in Oracle Forms 10g

    Below is the example to write file on client in Oracle Forms 10g with webutil library package.Note:  ...

  6. 让下拉框中同时显示Key与Value

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  7. Compounding绑定属性

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  8. 理解RxJava线程模型

    RxJava作为目前一款超火的框架,它便捷的线程切换一直被人们津津乐道,本文从源码的角度,来对RxJava的线程模型做一次深入理解.(注:本文的多处代码都并非原本的RxJava的源码,而是用来说明逻辑 ...

  9. b.Connector配置解析

    前面讲解到Tomcat中使用Digester框架进行server.xml到javaBean对象的映射,这篇文章以Connector的SSL通道为例,来讲解Connector的属性是如何注入的. 先看一 ...

  10. 【bzoj1084】最大子矩阵

    题意 这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大.注意:选出的k个子矩阵不能相互重叠. \(1≤n≤100,1≤m≤2,1≤k≤10\) 分析 由于\(m\)只有两 ...