1. プログラムプロセススレッドコンセプト_プロセス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): すべてのプロセスの親プロセス
2. メッセージキュー
#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 権限で実行すると正常にメッセージを受信できることがわかりました。後でもう一度メッセージを送信した後、3 回送信しなければならなかったことがわかりました。そのとき初めて 4 回目にメッセージを受信しました。何度か試しても同じことが起こりました。理由はわかりません。
ipcsコマンドで確認してください
--------- 消息队列 -----------
键 msqid 拥有者 权限 已用字节数 消息
0x00000522 0 root 0 0 0
プログラムを再コンパイルしても動作しないので、仮想マシンを再起動すると、プログラムに root 権限があることがわかります。再コンパイルしたらうまくいきました。
ipcsコマンドで再確認したところ、所有者と権限が変更されていました。
3. 共有メモリ
#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;
}
実行結果:
1 つのプロセスは共有メモリに書き込み、別のプロセスは共有メモリから読み取ります。
書く
#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;
}
読む
#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
もう一度読む
4. ミューテックスロック
スレッドで使用される
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 回印刷し、その後ロックを解除します。