网易博客转载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。