网易博客转载UNIX C学习(1部分)
来源:互联网 发布:mysql注释方式 编辑:程序博客网 时间:2024/06/11 10:30
1.进程间通信:
进程间通信 (INTER PROCESS COMMUNICATION 简称 IPC ),方式有:普通文件(fork) 有名管道、无名管道、内存映射、消息队列、socket文件、网络通信 。
方式有:普通文件(fork) 有名管道、无名管道、内存映射、消息队列、socket文件、网络通信
消息队列的代码:
发送端的代码
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <string.h>
int main()
{
key_t key = ftok(".", 102);//产生一个key
int msgid = msgget( key, IPC_CREAT|IPC_EXCL|0644);//得到此消息队列的id
int i=0;
char buf[100]="Hello World";
msgsnd( msgid, buf, strlen(buf)+1, 0);//发送消息
msgctl( msgid, IPC_RMID, NULL);//删除此消息队列
}
接收端的代码
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
int main()
{
key_t key = ftok(".", 102);
int msgid = msgget( key, 0);
int i=0;
char buf[100]={0};
msgrcv( msgid, buf, 100, 0,0 );//接收消息
printf("%s\n",buf);
}
注:发送端和接收端只要知道消息队列的id就可以通信了
共享内存段:
发送端:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <string.h>
int main()
{
key_t key = ftok(".", 102);
int shmid = shmget( key, 4096,IPC_CREAT|0644);
char * p = (char*)shmat( shmid, NULL, 0);
char buf[100]="Hello World";
strcpy(p,buf);
shmdt(p);
}
接收端:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <string.h>
int main()
{
key_t key = ftok(".", 102);
int shmid = shmget( key, 0, 0 );
char * p = (char*)shmat( shmid, NULL, 0);
char buf[100]={0};
strcpy(buf,p);
shmdt(p);
printf("%s\n",buf);
shmctl( shmid, IPC_RMID, NULL);
}
int shmctl(int shmid, int cmd, struct shmid_ds *buf); 得到共享内存段属性
//无名管道 (无名管道只用于父子进程之间。)
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int main()
{
int pipefd[2];
pipe( pipefd );//pipefd[0] read pipefd[1] write
int res = fork();
if(res>0)//parent process
{
close(pipefd[0]);
char buf[100] = "hello ,i am parent";
write( pipefd[1], buf , strlen(buf)+1 );
}
else if(res == 0)//child process
{
close(pipefd[1]);
char buf[100] = {0};
read( pipefd[0], buf , 100 );
printf("%s\n",buf)
}
}
命名管道:发送端:
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main()
{
mkfifo( "a.fifo", 0644);
int fd = open( "a.fifo", O_RDWR);
char buf[100]="hello ,world";
write( fd, buf, strlen(buf)+1 );
while(1);//命名管道不能退出,否则端不能收到数据
}
接收端
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main()
{
mkfifo( "a.fifo", 0644);
int fd = open( "a.fifo", 0);
char buf[100]={0};
read( fd, buf, 100 );
printf("%s\n",buf);
}
信号量:
信号量(SEMAPHORE)则是防止两个或多个进程同时访问共享资源的一种机制。下面程序保证对资源p[0]访问同时只能有一个进程访问。
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
key_t key = ftok( ".", 130);
int shmid = shmget( key, 0, 0);
int * p = (int *)shmat( shmid, NULL, 0);
int semid = semget( key, 0, 0);
struct sembuf sops[2] = {0};
sops[0].sem_num = 0;//信号集中的第几个信号
sops[0].sem_op = -1;//对信号 0 进行的操作 对信号 +1
sops[0].sem_flg = 0;
sops[1].sem_num = 1;//信号集中的第几个信号
sops[1].sem_op = 1;//对信号 1 进行的操作 对信号 -1
sops[1].sem_flg = 0;
struct semid_ds sd;
semctl( semid, 0, IPC_STAT, &sd);
printf("sd.sem_perm.uid = %d\n",sd.sem_perm.uid);
while(1)
{
semop(semid,sops,2);
printf("%d\t",p[0]);
fflush(stdout);
}
shmdt(p);
}
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/*The calling program must define this union as follows:*/
union semun {
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* Array for GETALL, SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO
(Linux-specific) */
};
int main()
{
key_t key = ftok( ".", 130);
int shmid = shmget( key, 4096, IPC_CREAT|0600);
int * p = (int *)shmat( shmid, NULL, 0);//挂接共享内存段
int semid = semget( key, 3, IPC_CREAT|0600);//为这个IPC设置信号,信号集中有3个信号
/*union semun un;
un.val = 0;*///程序也可以通过union semun 设定值,具体看文档
semctl(semid,0,SETVAL,0);//第 0 个信号的初始值为 0
semctl(semid,1,SETVAL,1);//第 1 个信号的初始值为 1
struct sembuf sops[2] = {0};
sops[0].sem_num = 0;//信号集中的第几个信号
sops[0].sem_op = 1;//对信号 0 进行的操作 对信号 +1
sops[0].sem_flg = 0;
sops[1].sem_num = 1;//信号集中的第几个信号
sops[1].sem_op = -1;//对信号 1 进行的操作 对信号 -1
sops[1].sem_flg = 0;
int cnt = 0;
for(cnt = 0;cnt<10;cnt++)
{
semop(semid,sops,2);//将 第 0 个信号+1,变成1,第1个信号 -1,变成 0,此时其它进程不能访问
p[0] = cnt;
sleep(1);
}
shmdt(p);
}
SOCKET通信
线程:
#include <pthread.h>
#include <stdio.h>
//线程1从1 + *p,并将结果返回
int sumcnt;
void * Thread1Proc(void * p)
{
int * pend = (int*) p;
int i=0;int sum = 0;
for(i = 1;i<*pend;i++)
sum+=i;
sumcnt = sum;
return &sumcnt;
}
void * Thread2Proc(void * p)
{
pthread_exit("hello,i am Thread2Proc");//此函数是线程退出值,本线程返回值为 字符串 首地址
}
int main()
{
pthread_t pid;
int cnt = 10;
pthread_create(&pid,NULL,Thread1Proc,&cnt);
int * pThread1Values;
pthread_join(pid,(void**)&pThread1Values);//等待线程1结束,并将结果返回到pThread1Values中。
printf("Thread1Values=%d\n",Thread1Values);
char * pThread2Values;
pthread_join(pid,(void **)&pThread2Values);
printf("Thread2Values=%s\n",pThread2Values);//返回值为hello,i am Thread2Proc
pthread_t pself = pthread_self();//返回当前运行线程(当前占用CPU资源的线程id)
printf("pself = %d\n",(int)pself);
}
//线程返回时,不能返回局部变量的地址,因为每个线程都有自己独立的栈空间,当线程开始运行时,分配栈空间,当线程结束时,此栈空间已经释放,再返回它的地址,但是其值已经不在。所有线程共用进程内的代码段、堆段,因此如果在线程1中通过堆空间分配,将堆空间地址返回,也可以。
//线程编译时,要 -l pthread, pthread_equal(t1,t2):如果两个线程id相等,则返回非0值,否则返回 0值。
//pthread_attr_init();初始化线程属性为默认。
//pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED):设置一个脱管线程,当线程被脱管后,不能join它。
//pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL); 设置线程取消状态,此函数中参数表示线程不能取消
//pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,NULL); 设置线程取消类型,此函数中参数表示线程到取消点取消,被取消的线程需要join来释放资源。被取消的线程的返回值为PTHREAD_CANCELED。
- 网易博客转载UNIX C学习(1部分)
- 网易博客转载UNIX C学习(2部分)
- 网易博客转载UNIX C学习(3部分)
- 网易博客转载UNIX C学习(4部分)
- 网易博客转载C学习(1部分)
- 网易博客转载C++学习(1部分)
- 从今天开始,我将开始转载网易博客部分文章
- 网易博客#include<cstdio>转载
- unix c学习总结--线程部分(apue)
- 【转载网易博客】select @@identity的用法
- uml开发过程转载自网易博客
- 我的网易学习博客
- 学习日记+部分转载
- 学习博客指南-转载
- (iOS 开发) 证书部分的博客转载
- 【转载】网易博客完美支持Word写日志
- 浏览器 cookie 详解 -- 转载自网易博客gkecenter
- 二叉树遍历——转载于网易博客summer
- c 语言函数总结篇access(),sscanf()
- java io
- 笔记提交地址
- 关于“设备驱动程序”
- android sd卡存储容量
- 网易博客转载UNIX C学习(1部分)
- Conversion to Dalvik format failed with error 1解决办法
- JAVA 快速实现webService (同步逻辑)
- java怎么把一个string个日期类型 如“Fri Feb 01 00:00:00 GMT+08:00 2013”转换成“yyyy-mm-dd”
- 大话设计模式_简单工厂模式
- jQuery UI库使用记录----menu
- 网易博客转载UNIX C学习(2部分)
- 排序
- 黑马程序员 反射