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 //生成可重入代码

程序运行结果:
[email protected]:/mnt/hgfs/source test/file IO$ gcc test13.c -lpthread -D_REENTRANT
[email protected]:/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");
}

上面程序的运行结果:
[email protected]:/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
[email protected]:/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相等)
[email protected]:/mnt/hgfs/source test/file IO$ gcc lock14.c -lpthread -D_REENTRANT
[email protected]:/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
[email protected]:/mnt/hgfs/source test/file IO$ ^C
[email protected]:/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才对,有待解决)
[email protected]:/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
[email protected]:/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
[email protected]:/mnt/hgfs/source test/file IO$

***************************************************************************************************************************************************************
***************************************************************************************************************************************************************
***************************************************************************************************************************************************************
***************************************************************************************************************************************************************

时间: 2024-08-22 00:06:04

exec函数族,守护进程,线程同步和互斥的相关文章

操作系统:进程/线程同步的方式和机制,进程间通信

一.进程/线程间同步机制. 临界区.互斥区.事件.信号量四种方式临界区(Critical Section).互斥量(Mutex).信号量(Semaphore).事件(Event)的区别1.临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问.在任意时刻只允许一个线程对共享资源进行访问,如果有多个线程试图访问公共资源,那么在有一个线程进入后,其他试图访问公共资源的线程将被挂起,并一直等到进入临界区的线程离开,临界区在被释放后,其他线程才可以抢占.2.互斥量:采用互斥对象机

进程/线程同步的方式和机制,进程间通信

转自: http://www.cnblogs.com/memewry/archive/2012/08/22/2651696.html 一.进程/线程间同步机制. 临界区.互斥区.事件.信号量四种方式临界区(Critical Section).互斥量(Mutex).信号量(Semaphore).事件(Event)的区别1.临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问.在任意时刻只允许一个线程对共享资源进行访问,如果有多个线程试图访问公共资源,那么在有一个线程进入后

一起talk C栗子吧(第一百一十六回:C语言实例--线程同步之互斥量二)

各位看官们,大家好,上一回中咱们说的是线程同步之信号量的例子,这一回咱们继续说该例子.闲话休提,言归正转.让我们一起talk C栗子吧! 我们在上一回中详细介绍了互斥量相关函数的用法,这一回中,我们介绍如何使用这些函数来操作互斥量. 下面是详细的操作步骤: 1.定义一个互斥量A,用来同步线程: 2.在创建线程的进程中使用pthread_mutex_init函数初始化互斥量,互斥量的属性使用默认值: 3.在读取数据的线程中读取数据,首先使用pthread_mutex_lock函数对互斥量A进行加锁

Linux系统编程——线程同步与互斥:无名信号量

信号量概述 信号量广泛用于进程或线程间的同步和互斥,信号量本质上是一个非负的整数计数器,它被用来控制对公共资源的访问. 编程时可根据操作信号量值的结果判断是否对公共资源具有访问的权限,当信号量值大于 0 时,则可以访问,否则将阻塞.PV 原语是对信号量的操作,一次 P 操作使信号量减1,一次 V 操作使信号量加1. 信号量主要用于进程或线程间的同步和互斥这两种典型情况. 信号量用于互斥: 信号量用于同步: 在 POSIX 标准中,信号量分两种,一种是无名信号量,一种是有名信号量.无名信号量一般用

用信号量解决进程的同步与互斥探讨【持续更新】

现代操作系统采用多道程序设计机制,多个进程可以并发执行,CPU在进程之间来回切换,共享某些资源,提高了资源的利用率,但这也使得处理并发执行的多个进程之间的冲突和相互制约关系成为了一道难题.如果对并发进程的调度不当,则可能会出现运行结果与切换时间有关的情况,令结果不可再现,影响系统的效率和正确性,严重时还会使系统直接崩溃.就比如你只有一台打印机,有两个进程都需要打印文件,如果直接让他们简单地并发访问打印机,那么你很可能什么都打印不出来或者打印的文件是...anyway,我们需要增加一些机制来控制并

线程同步与互斥:POSIX无名信号量

信号量概述 信号量广泛用于进程或线程间的同步和互斥,信号量本质上是一个非负的整数计数器,它被用来控制对公共资源的访问. 编程时可根据操作信号量值的结果判断是否对公共资源具有访问的权限,当信号量值大于 0 时,则可以访问,否则将阻塞.PV 原语是对信号量的操作,一次 P 操作使信号量减1,一次 V 操作使信号量加1. 信号量主要用于进程或线程间的同步和互斥这两种典型情况. 信号量用于互斥: 信号量用于同步: 在 POSIX 标准中,信号量分两种,一种是无名信号量,一种是有名信号量.无名信号量一般用

Android多线程研究(3)——线程同步和互斥及死锁

为什么会有线程同步的概念呢?为什么要同步?什么是线程同步?先看一段代码: package com.maso.test; public class ThreadTest2 implements Runnable{ private TestObj testObj = new TestObj(); public static void main(String[] args) { ThreadTest2 tt = new ThreadTest2(); Thread t1 = new Thread(tt,

计算机操作系统学习笔记_5_进程管理 -- 同步与互斥

h3.western { font-family: "Liberation Sans",sans-serif; }h3.cjk { font-family: "微软雅黑"; }h3.ctl { font-family: "AR PL UMing CN"; }h2.western { font-family: "Liberation Sans",sans-serif; font-size: 16pt; }h2.cjk { fon

线程同步与互斥之条件·变量

条件变量(condition variable) 线程间的同步与互斥技术,主要以互斥锁和条件变量为主,条件变量和互斥所的配合使用可以很好的处理对于条件等待的线程间的同步问题.举个例子:消费者和生产者问题. 消费者与生产者最基本的关系是服务与被服务的关系,但是在线程同步与互斥中强调的是两者访问资源的关系.首先生产与消费的关系为:同步与互斥,生产与生产的关系为:互斥,消费与消费的关系为:互斥.所以维护这三种关系的有两类人:生产者与消费者.并且生产数据与消费数据必须有场所. 所以将其简述为三种关系两类