本文记录Linux编程中会遇到的很多的相关的术语,持续更新
1. 同步和异步
这里举windows编程的消息发送函数很恰当,
SendMessage(). // 发送指定消息直到消息处理函数处理了该消息才将结果返回。可以理解为,要执行的步骤比较多,一直等到执行完才往下执行其他步骤,代码如下
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
void printSync(const char *str)
{
sleep(1); // assume this will do lots of thing
puts(str);
sleep(1); // assume this also will do lots of thing
}
void *thread_proc(void *data)
{
const char *str = data;
sleep(1);
puts(str);
sleep(1);
return (void *)0;
}
pthread_t tid;
void printAsync(const char *str)
{
pthread_create(&tid, NULL, thread_proc, (void *)str);
}
int main()
{
printSync("I am Sync call");
printAsync("I am a Async call");
puts("end");
pthread_join(tid, NULL);
return 0;
}
上面的例子可以反应出同步调用和异步调用的区别,只是一般的异步调用都会采用异步回调的机制,只需要将函数指针写到参数然后创建的新线程解析出来后当线程执行完成时调用指定回调函数即可。
2. 阻塞和非阻塞
阻塞是在要访问的资源不确定是否存在的情况下等待,阻塞和同步的区别在于阻塞并不知道要等待多久,也许一直等待。
非阻塞是查询式的,如果没有资源则立马返回报错或定时下次再去查询。
举个管道的例子来说明阻塞
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
char buf[1024] = {0,};
int fd[2];
if (0 != pipe(fd))
{
perror("pipe error");
exit(1);
}
// read the pipe[0] when the pipe[1] not be writed
read(fd[0], buf, 1024);
// all will not be exec
puts("read over");
close(fd[0]);
close(fd[1]);
return 0;
}
# ./a.out 会一直等待,读管道阻塞
而epoll就是一个非阻塞的读文件的方法
3. 并发和并行
并发指任务的调度是有先后顺序的,执行任务的切换时间很快,对调用者来说好像是同时执行的,实际上是串行的。
并行指两个线程同时执行,只有在多核或者多cpu的情况下存在
4.线程同步和互斥
两个线程A, B
互斥: 访问临界资源, 比如A,B都要访问打印机,则在某一刻只能有一个线程访问, <在上面的例子中进行改写>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *thr_fnA(void *arg)
{
printf("thrA running...\n");
return (void *)23;
}
void *thr_fnB(void *arg)
{
printf("thrB running...\n");
pthread_exit((void *)34);
}
int main()
{
pthread_t ntidA, ntidB;
pthread_create(&ntidA, NULL, thr_fnA, NULL);
pthread_create(&ntidB, NULL, thr_fnB, NULL);
<pre name="code" class="cpp"> pthread_join(ntidA, NULL);
pthread_join(ntidB, NULL); exit(0);}
互斥: 访问临界资源, 比如A,B都要访问打印机,则在某一刻只能有一个线程访问, <在上面的例子中进行改写>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
<span style="color:#FF0000;">
pthread_mutex_t Mutex = PTHREAD_MUTEX_INITIALIZER;</span>
int i = 0;
void *thr_fnA(void *arg)
{
printf("thrA running...\n");
<span style="color:#FF0000;">pthread_mutex_lock(&Mutex);</span>
i++; i++; i++; i++;
sleep(3); // when thrA hold the lock, thrB will wait
i++; i++; i++; i++;
<span style="color:#FF0000;">pthread_mutex_unlock(&Mutex);</span>
printf("thrA end...\n");
return (void *)23;
}
void *thr_fnB(void *arg)
{
sleep(1); // be sure thrA run before B out
printf("thrB running...\n");
<span style="color:#FF0000;">pthread_mutex_lock(&Mutex);</span>
i++; i++; i++; i++;
i++; i++; i++; i++;
<span style="color:#FF0000;">pthread_mutex_unlock(&Mutex);</span>
printf("thrB end...\n");
pthread_exit((void *)34);
}
int main()
{
pthread_t ntidA, ntidB;
pthread_create(&ntidA, NULL, thr_fnA, NULL);
pthread_create(&ntidB, NULL, thr_fnB, NULL);
pthread_join(ntidA, NULL);
pthread_join(ntidB, NULL);
printf("The i is %d\n", i);
exit(0);
}
同步: 控制两个线程的执行顺序, 如果 A 是 向缓存区中写数据,B从其中读, 则应该要保证A先写入然后 B 执行,<下面的程序保证B在A前面执行操作>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
pthread_mutex_t Mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t Cond = PTHREAD_COND_INITIALIZER;
int i = 0;
void *thr_fnA(void *arg)
{
printf("thrA running...\n");
pthread_mutex_lock(&Mutex); <pre name="code" class="cpp"> // when the wait begin, the mutex will be unlock, so the thrB can lock the mutex,
// and when the wait is over, thrA will try to lock mutex again
pthread_cond_wait(&Cond, &Mutex); pthread_mutex_unlock(&Mutex); printf("thrA end...\n"); return (void *)23;}void *thr_fnB(void *arg){ usleep(1); // be sure thrA will run before thrB running printf("thrB running...\n"); pthread_mutex_lock(&Mutex); pthread_cond_signal(&Cond); sleep(3); // this time the mutex is be locked by thrB, so thrA will wait for B's unlock pthread_mutex_unlock(&Mutex); printf("thrB end...\n"); pthread_exit((void *)34);}int main(){ pthread_t ntidA, ntidB; pthread_create(&ntidA, NULL, thr_fnA, NULL); pthread_create(&ntidB, NULL, thr_fnB, NULL); pthread_join(ntidA, NULL); pthread_join(ntidB, NULL); printf("The i is %d\n", i); exit(0);}