Linux系统编程代码汇总

一.程序进程线程概念_进程ID号

程序:源代码,指令

进程:运行着的程序

线程:线程从属于进程,一个进程可以有多个线程,线程直接共享进程的资源

任务:具体要做的事情

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>

int main(void)
{
	pid_t pid;

	while(1)
	{
		printf("pid = %d\n", getpid()); //当前进程id号
		printf("ppid = %d\n", getppid());//当前进程父进程id号
		printf("Hello world\n");
		sleep(1);
	}

	return 0;
}

运行结果:

 pstree -p

可以查看我们的进程树,就是进程关系

 

systemd(init): 所有进程的父进程

二.消息队列

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/msg.h>

#define MY_TYPE  9527

int main(void)
{
	int msgid;
	pid_t pid;

	struct msgbuf
	{
		long mtype;
		char mtext[100];
		int number;
	};

	struct msgbuf buff;

	msgid = msgget(IPC_PRIVATE, 0666 | IPC_EXCL); /* 不晓得为什么必须加上0666才可以*/

	if (msgid == -1) {
	    perror("msgget");
	    return -1;
	}

	pid = fork();

	if(pid > 0)
	{
	    sleep(1);

		buff.mtype = MY_TYPE;
		printf("Please enter a string you want to send:\n");
		gets(buff.mtext);
		printf("Please enter a nubmer you want to send:\n");
		scanf("%d", &buff.number);

		msgsnd(msgid, &buff, sizeof(buff) - sizeof(buff.mtype), 0);

		waitpid(pid, NULL, 0);
	}
	else if(pid == 0)
	{
		printf("Child process is waiting for msg:\n");
		msgrcv(msgid, &buff, sizeof(buff) - sizeof(buff.mtype), MY_TYPE, 0);
		printf("Child process read from msg: %s, %d\n", buff.mtext, buff.number);
	}
	else
		perror("fork");

	return 0;
}

运行效果:

用消息队队列让不同进程之间通信

接收部分代码

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/msg.h>

#define MY_TYPE  9527
#define MY_KEY	 1314

int main(void)
{
	int msgid;

	struct msgbuf
	{
		long mtype;
		char mtext[100];
		int number;
	};

	struct msgbuf buff;

	msgid = msgget(MY_KEY, IPC_CREAT|0644);

	while(1)
	{
		printf("Process is waiting for msg:\n");
		msgrcv(msgid, &buff, sizeof(buff) - sizeof(buff.mtype), MY_TYPE, 0);
		printf("Process read from msg: %s, %d\n", buff.mtext, buff.number);
	}
	msgctl(msgid, IPC_RMID, NULL);

	return 0;
}

发送部分代码

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/msg.h>

#define MY_TYPE  9527
#define MY_KEY	 1314

int main(void)
{
	int msgid;

	struct msgbuf
	{
		long mtype;
		char mtext[100];
		int number;
	};

	struct msgbuf buff;

	msgid = msgget(MY_KEY, IPC_CREAT); //ftok

	buff.mtype = MY_TYPE;
	printf("Please enter a string you want to send:\n");
	gets(buff.mtext);
	printf("Please enter a nubmer you want to send:\n");
	scanf("%d", &buff.number);

	msgsnd(msgid, &buff, sizeof(buff) - sizeof(buff.mtype), 0);

	return 0;
}

 运行效果

 遇到的问题,一开始是没有用root 权限运行,导致接收消息的时候出现了死循环,但是后面发现用root权限运行之后,可以正常接收消息,但是后面再运行,发现我要发三次后,才能收到第四次的消息,试了几次都是这样,不清楚为什么。

用命令ipcs看了一下

--------- 消息队列 -----------
键        msqid      拥有者  权限     已用字节数 消息      
0x00000522 0          root       0          0            0

是这样的,怎么重新编译程序都不行,后面重新启动了虚拟机,发现程序是root权限的。我重新编译了一下,就可以了。

用命令ipcs重新看了一下,发现拥有者和权限那里已经变了。

三.共享内存

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>

char msg[] = "Hello world";

int main(void)
{
	int shmid;
	pid_t pid;

	shmid = shmget(IPC_PRIVATE, 1024, IPC_CREAT);

	pid = fork();

	if(pid > 0)
	{
		char *p_addr;
		p_addr = shmat(shmid, NULL, 0);

		memset(p_addr, '\0', sizeof(msg));
		memcpy(p_addr, msg, sizeof(msg));

		shmdt(p_addr);

		waitpid(pid, NULL, 0);
	}
	else if(pid == 0)
	{
		char *c_addr;
		c_addr = shmat(shmid, NULL, 0);

		printf("Child process waits a short time: \n");
		sleep(3);
		printf("Child Process reads from shared memory: %s\n", c_addr);
		shmdt(c_addr);
	}
	else
		perror("fork");

	return 0;
}

运行效果:

一个进程写共享内存,另外一个进程读共享内存

write

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>

char msg[] = "Hello world";

#define MY_KEY	9527

int main(void)
{
	int shmid;

	shmid = shmget(MY_KEY, 1024, IPC_CREAT);

	char *p_addr;
	p_addr = shmat(shmid, NULL, 0);

	memset(p_addr, '\0', sizeof(msg));
	memcpy(p_addr, msg, sizeof(msg));

	shmdt(p_addr);

//	shmctl(shmid, IPC_RMID, NULL);

	return 0;
}

read

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>

#define MY_KEY	9527

int main(void)
{
	int shmid;

	shmid = shmget(MY_KEY, 1024, IPC_CREAT);

	char *c_addr;
	c_addr = shmat(shmid, NULL, 0);

	printf("Read from shared memory: %s\n", c_addr);
	shmdt(c_addr);

	return 0;
}

 运行效果:

先write

再read

四.互斥锁

用在线程中

pthread_mutex_init  初始化互斥锁

pthread_mutex_lock(&mutex) 上锁

要做的事情

pthread_mutex_unlock(&mutex) 解锁

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <semaphore.h>

void *thread1_function(void *arg);
void *thread2_function(void *arg);

pthread_mutex_t mutex;

int main(void)
{
	pthread_t pthread1, pthread2;
	int ret;

	pthread_mutex_init(&mutex, NULL);

	ret = pthread_create(&pthread1, NULL, thread1_function, NULL);
	if(ret != 0)
	{
		perror("pthread_create");
		exit(1);
	}

	ret = pthread_create(&pthread2, NULL, thread2_function, NULL);
	if(ret != 0)
	{
		perror("pthread_create");
		exit(1);
	}

	pthread_join(pthread1, NULL);
	pthread_join(pthread2, NULL);
	printf("The thread is over, process is over too.\n");

	return 0;
}

void *thread1_function(void *arg)
{
	int i;

	while(1)
	{
		pthread_mutex_lock(&mutex);
		for(i = 0; i < 10; i++)
		{
			printf("Hello world\n");
			sleep(1);
		}
		pthread_mutex_unlock(&mutex);
		sleep(1);
	}
	return NULL;
}

void *thread2_function(void *arg)
{
	int i;
	sleep(1);

	while(1)
	{
		pthread_mutex_lock(&mutex);
		for(i = 0; i < 10; i++)
		{
			printf("Good moring\n");
			sleep(1);
		}
		pthread_mutex_unlock(&mutex);
		sleep(1);
	}
	return NULL;
}

运行效果:先上锁,线程先打印10次,再解锁

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Unix/Linux系统编程是指使用C语言编写程序,能够调用操作系统提供的系统调用和库函数来完成系统级任务的程序设计过程。Unix/Linux系统编程的目的是编写高效、可靠、安全、移植性好的应用程序或系统程序。 Unix/Linux系统编程的核心代码包括使用系统调用,文件操作(读写文件、目录操作等),进程控制(fork、exec等),信号处理,网络编程等。 在Unix/Linux中,系统调用是与内核进行通讯的标准方式。程序中使用系统调用来请求内核完成某个任务。例如,open()系统调用用于打开一个文件,并返回文件描述符。read()和write()系统调用用于读写文件。 文件操作是Unix/Linux系统编程中的一个重要部分。文件操作包括打开文件、读写文件、删除文件、重命名文件等操作。另外还有目录操作,如创建目录、删除目录、遍历目录等。 进程控制是Unix/Linux系统编程中最为复杂的部分之一。进程控制包括创建新进程、执行新进程、等待进程结束、发送信号给进程等等。其中最常见的系统调用是fork()和exec()。fork()用于创建新进程,而在创建新进程之后,exec()则用于在新进程中执行新的程序。 信号处理是Unix/Linux系统编程中的一个重要概念。信号是由系统发出的一个异步事件,可以从进程内部或外部发出。进程可以对信号进行相应操作。常见的信号包括SIGINT(Ctrl+C中断信号)、SIGTERM(终止进程信号)和SIGKILL(强制终止进程信号)。 网络编程是Unix/Linux系统编程中的另一个重要部分。Unix/Linux提供了许多网络编程API,例如socket()、bind()、listen()和accept()等。使用这些API可以编写服务器端和客户端程序,进行网络通信。 总之,Unix/Linux系统编程涉及到许多重要的概念和操作,涉及到操作系统底层的各种操作。因此,需要开发人员有扎实的C编程能力、熟悉Unix/Linux系统调用和库函数、了解进程控制和信号处理的概念、熟悉网络编程API以及充分了解操作系统内部的机制。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值